From 9373da58e98e9e66d43dc272ee26bdc7c6d352c1 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 26 Jan 2023 17:21:25 +0100 Subject: [PATCH 01/19] Fix for #6321 --- .../Rules/UnusedPrivateMember.cs | 16 +++++++++++++++- .../Rules/UnusedPrivateMemberTest.Methods.cs | 2 +- .../Rules/UnusedPrivateMemberTest.Types.cs | 2 +- .../TestCases/UnusedPrivateMember.cs | 5 +++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index 3cc6333f5fe..bcb53aad795 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +using Microsoft.CodeAnalysis; using SonarAnalyzer.Constants; namespace SonarAnalyzer.Rules.CSharp @@ -41,6 +42,14 @@ public sealed class UnusedPrivateMember : SonarDiagnosticAnalyzer KnownType.UnityEngine_ScriptableObject, KnownType.Microsoft_EntityFrameworkCore_Migrations_Migration); + private static readonly SyntaxKind[] SyntaxKindsToOnlyShowIdentifierLocation = new[] + { + SyntaxKindEx.RecordClassDeclaration, + SyntaxKindEx.RecordStructDeclaration, + SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, + SyntaxKind.MethodDeclaration + }; + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(RuleS1144, RuleS4487); protected override bool EnableConcurrentExecution => false; @@ -215,9 +224,14 @@ static IEnumerable GetSiblingDeclarators(SyntaxNode va }; Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => - Diagnostic.Create(RuleS1144, syntaxNode.GetLocation(), accessibility, symbol.GetClassification(), GetMemberName(symbol)); + Diagnostic.Create(RuleS1144, GetIssueLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); } + private static Location GetIssueLocation(SyntaxNode syntaxNode) => + syntaxNode.IsAnyKind(SyntaxKindsToOnlyShowIdentifierLocation) && syntaxNode.GetIdentifier().HasValue + ? syntaxNode.GetIdentifier().Value.GetLocation() + : syntaxNode.GetLocation(); + private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IReadOnlyDictionary propertyAccessorAccess) { var access = propertyAccessorAccess[property]; diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Methods.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Methods.cs index b7c17d0ef6c..e2387079968 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Methods.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Methods.cs @@ -28,7 +28,7 @@ public void UnusedPrivateMember_Method_Accessibility() => public class PrivateMembers { private int PrivateMethod() { return 0; } // Noncompliant {{Remove the unused private method 'PrivateMethod'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^^^^^^^^ private static int PrivateStaticMethod() { return 0; } // Noncompliant private class InnerPrivateClass // Noncompliant diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Types.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Types.cs index b1460ec7429..0b83c5f6d24 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Types.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Types.cs @@ -35,7 +35,7 @@ public class PublicClass { } // Noncompliant } private class PrivateClass { } // Noncompliant -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^^^^^^^ internal class InternalClass { } // Noncompliant private struct PrivateStruct { } // Noncompliant diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index b6720c8f2bb..7a5e3a8df42 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -67,10 +67,11 @@ private int Property // Noncompliant {{Remove the unused private property 'Prope get; set; } private void Method() { } // Noncompliant {{Remove the unused private method 'Method'.}} +// ^^^^^^ private class Class { }// Noncompliant {{Remove the unused private class 'Class'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^ private struct Struct { }// Noncompliant {{Remove the unused private struct 'Struct'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^ private delegate void Delegate(); private delegate void Delegate2(); // Noncompliant {{Remove the unused private delegate 'Delegate2'.}} private event Delegate Event; //Noncompliant {{Remove the unused private event 'Event'.}} From 72ef5d9f08f6a85db738dea3a20c168cfd71d709 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 26 Jan 2023 17:25:11 +0100 Subject: [PATCH 02/19] Update Sarif files --- ...4a4-59fd-497b-bb52-4414b1320d29-S1144.json | 24 +++--- .../expected/Nancy/Nancy--net452-S1144.json | 18 ++-- .../Nancy/Nancy--netstandard2.0-S1144.json | 18 ++-- .../Nancy/Nancy.Testing--net452-S1144.json | 6 +- .../Nancy.Testing--netstandard2.0-S1144.json | 6 +- .../its/expected/Net5/Net5--net5.0-S1144.json | 86 +++++++++---------- .../its/expected/Net7/Net7--net7.0-S1144.json | 28 +++--- ...4a4-59fd-497b-bb52-4414b1320d29-S1144.json | 24 +++--- .../akka.net/Akka--netstandard2.0-S1144.json | 18 ++-- .../Akka.Benchmarks--netcoreapp3.1-S1144.json | 6 +- .../Akka.Cluster--netstandard2.0-S1144.json | 6 +- ...kka.MultiNodeTestRunner--net471-S1144.json | 12 +-- ...kka.MultiNodeTestRunner--net5.0-S1144.json | 12 +-- ...tiNodeTestRunner--netcoreapp3.1-S1144.json | 12 +-- ...ence.Sql.Common--netstandard2.0-S1144.json | 12 +-- ...Persistence.TCK--netstandard2.0-S1144.json | 12 +-- .../Akka.Remote--netstandard2.0-S1144.json | 6 +- .../Akka.Streams--netstandard2.0-S1144.json | 10 +-- ...Streams.TestKit--netstandard2.0-S1144.json | 6 +- .../Akka.TestKit--netstandard2.0-S1144.json | 12 +-- 20 files changed, 167 insertions(+), 167 deletions(-) diff --git a/analyzers/its/expected/AnalyzeGenerated.CS/AnalyzeGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json b/analyzers/its/expected/AnalyzeGenerated.CS/AnalyzeGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json index 8832ac1eafa..98dea8cae89 100644 --- a/analyzers/its/expected/AnalyzeGenerated.CS/AnalyzeGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json +++ b/analyzers/its/expected/AnalyzeGenerated.CS/AnalyzeGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\GeneratedCode.CS\generated_region.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 21, +"endLine": 7, +"endColumn": 27 } } }, @@ -20,9 +20,9 @@ "uri": "sources\GeneratedCode.CS\generated_region_2.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 21, +"endLine": 7, +"endColumn": 27 } } }, @@ -33,9 +33,9 @@ "uri": "sources\GeneratedCode.CS\handwritten.cs", "region": { "startLine": 8, -"startColumn": 9, -"endLine": 12, -"endColumn": 10 +"startColumn": 21, +"endLine": 8, +"endColumn": 27 } } }, @@ -46,9 +46,9 @@ "uri": "sources\GeneratedCode.CS\handwritten.cs", "region": { "startLine": 14, -"startColumn": 9, -"endLine": 16, -"endColumn": 10 +"startColumn": 22, +"endLine": 14, +"endColumn": 25 } } } diff --git a/analyzers/its/expected/Nancy/Nancy--net452-S1144.json b/analyzers/its/expected/Nancy/Nancy--net452-S1144.json index 046e44810e0..d3adb2f71fb 100644 --- a/analyzers/its/expected/Nancy/Nancy--net452-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy--net452-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\Nancy\src\Nancy\Bootstrapper\NancyBootstrapperLocator.cs", "region": { "startLine": 66, -"startColumn": 9, -"endLine": 82, -"endColumn": 10 +"startColumn": 29, +"endLine": 66, +"endColumn": 47 } } }, @@ -33,9 +33,9 @@ "uri": "sources\Nancy\src\Nancy\Routing\DefaultRouteCacheProvider.cs", "region": { "startLine": 76, -"startColumn": 13, -"endLine": 93, -"endColumn": 14 +"startColumn": 55, +"endLine": 76, +"endColumn": 67 } } }, @@ -46,9 +46,9 @@ "uri": "sources\Nancy\src\Nancy\TinyIoc\TinyIoC.cs", "region": { "startLine": 3843, -"startColumn": 9, -"endLine": 3846, -"endColumn": 10 +"startColumn": 24, +"endLine": 3843, +"endColumn": 37 } } } diff --git a/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json b/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json index 2f4c6fd7d4e..ae9d3681cc1 100644 --- a/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json @@ -33,9 +33,9 @@ "uri": "sources\Nancy\src\Nancy\Routing\DefaultRouteCacheProvider.cs", "region": { "startLine": 76, -"startColumn": 13, -"endLine": 93, -"endColumn": 14 +"startColumn": 55, +"endLine": 76, +"endColumn": 67 } } }, @@ -46,9 +46,9 @@ "uri": "sources\Nancy\src\Nancy\TinyIoc\TinyIoC.cs", "region": { "startLine": 3350, -"startColumn": 9, -"endLine": 3372, -"endColumn": 10 +"startColumn": 22, +"endLine": 3350, +"endColumn": 39 } } }, @@ -59,9 +59,9 @@ "uri": "sources\Nancy\src\Nancy\TinyIoc\TinyIoC.cs", "region": { "startLine": 3843, -"startColumn": 9, -"endLine": 3846, -"endColumn": 10 +"startColumn": 24, +"endLine": 3843, +"endColumn": 37 } } } diff --git a/analyzers/its/expected/Nancy/Nancy.Testing--net452-S1144.json b/analyzers/its/expected/Nancy/Nancy.Testing--net452-S1144.json index 5088988f06a..7dd7620c687 100644 --- a/analyzers/its/expected/Nancy/Nancy.Testing--net452-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy.Testing--net452-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\Nancy\src\Nancy.Testing\ConfigurableBootstrapper.cs", "region": { "startLine": 189, -"startColumn": 9, -"endLine": 192, -"endColumn": 10 +"startColumn": 31, +"endLine": 189, +"endColumn": 51 } } } diff --git a/analyzers/its/expected/Nancy/Nancy.Testing--netstandard2.0-S1144.json b/analyzers/its/expected/Nancy/Nancy.Testing--netstandard2.0-S1144.json index 5088988f06a..7dd7620c687 100644 --- a/analyzers/its/expected/Nancy/Nancy.Testing--netstandard2.0-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy.Testing--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\Nancy\src\Nancy.Testing\ConfigurableBootstrapper.cs", "region": { "startLine": 189, -"startColumn": 9, -"endLine": 192, -"endColumn": 10 +"startColumn": 31, +"endLine": 189, +"endColumn": 51 } } } diff --git a/analyzers/its/expected/Net5/Net5--net5.0-S1144.json b/analyzers/its/expected/Net5/Net5--net5.0-S1144.json index e05111ffe20..d44c2b938f8 100644 --- a/analyzers/its/expected/Net5/Net5--net5.0-S1144.json +++ b/analyzers/its/expected/Net5/Net5--net5.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\Net5\Net5\ExtendingPartial.cs", "region": { "startLine": 6, -"startColumn": 9, +"startColumn": 22, "endLine": 6, -"endColumn": 27 +"endColumn": 24 } } }, @@ -20,9 +20,9 @@ "uri": "sources\Net5\Net5\ExtendingPartial.cs", "region": { "startLine": 9, -"startColumn": 9, +"startColumn": 30, "endLine": 9, -"endColumn": 35 +"endColumn": 32 } } }, @@ -46,9 +46,9 @@ "uri": "sources\Net5\Net5\Records.cs", "region": { "startLine": 121, -"startColumn": 9, -"endLine": 127, -"endColumn": 10 +"startColumn": 22, +"endLine": 121, +"endColumn": 28 } } }, @@ -72,9 +72,9 @@ "uri": "sources\Net5\Net5\S1185.cs", "region": { "startLine": 10, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 16, +"endLine": 10, +"endColumn": 23 } } }, @@ -85,9 +85,9 @@ "uri": "sources\Net5\Net5\S2077.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 10, -"endColumn": 10 +"startColumn": 14, +"endLine": 7, +"endColumn": 17 } } }, @@ -111,9 +111,9 @@ "uri": "sources\Net5\Net5\S2612.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 12, -"endColumn": 10 +"startColumn": 14, +"endLine": 7, +"endColumn": 17 } } }, @@ -176,9 +176,9 @@ "uri": "sources\Net5\Net5\S3251.Part1.cs", "region": { "startLine": 5, -"startColumn": 9, +"startColumn": 22, "endLine": 5, -"endColumn": 31 +"endColumn": 28 } } }, @@ -189,9 +189,9 @@ "uri": "sources\Net5\Net5\S3251.Part1.cs", "region": { "startLine": 6, -"startColumn": 9, +"startColumn": 22, "endLine": 6, -"endColumn": 32 +"endColumn": 29 } } }, @@ -202,9 +202,9 @@ "uri": "sources\Net5\Net5\S3251.Part2.cs", "region": { "startLine": 5, -"startColumn": 9, +"startColumn": 22, "endLine": 5, -"endColumn": 32 +"endColumn": 29 } } }, @@ -293,9 +293,9 @@ "uri": "sources\Net5\Net5\S3776.cs", "region": { "startLine": 23, -"startColumn": 9, -"endLine": 28, -"endColumn": 89 +"startColumn": 14, +"endLine": 23, +"endColumn": 53 } } }, @@ -345,9 +345,9 @@ "uri": "sources\Net5\Net5\S4015.cs", "region": { "startLine": 10, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 15, +"endLine": 10, +"endColumn": 16 } } }, @@ -423,9 +423,9 @@ "uri": "sources\Net5\Net5\S4583.Part1.cs", "region": { "startLine": 9, -"startColumn": 9, -"endLine": 15, -"endColumn": 10 +"startColumn": 29, +"endLine": 9, +"endColumn": 97 } } }, @@ -436,9 +436,9 @@ "uri": "sources\Net5\Net5\S4583.Part1.cs", "region": { "startLine": 17, -"startColumn": 9, -"endLine": 23, -"endColumn": 10 +"startColumn": 29, +"endLine": 17, +"endColumn": 97 } } }, @@ -449,9 +449,9 @@ "uri": "sources\Net5\Net5\S4583.Part1.cs", "region": { "startLine": 25, -"startColumn": 9, -"endLine": 31, -"endColumn": 10 +"startColumn": 29, +"endLine": 25, +"endColumn": 97 } } }, @@ -462,9 +462,9 @@ "uri": "sources\Net5\Net5\S4583.Part1.cs", "region": { "startLine": 33, -"startColumn": 9, -"endLine": 39, -"endColumn": 10 +"startColumn": 29, +"endLine": 33, +"endColumn": 97 } } }, @@ -475,9 +475,9 @@ "uri": "sources\Net5\Net5\S4830.cs", "region": { "startLine": 5, -"startColumn": 9, -"endLine": 11, -"endColumn": 10 +"startColumn": 14, +"endLine": 5, +"endColumn": 17 } } }, diff --git a/analyzers/its/expected/Net7/Net7--net7.0-S1144.json b/analyzers/its/expected/Net7/Net7--net7.0-S1144.json index be9d2e57385..b2788190ee8 100644 --- a/analyzers/its/expected/Net7/Net7--net7.0-S1144.json +++ b/analyzers/its/expected/Net7/Net7--net7.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\Net7\Net7\features\GenericAttributes.cs", "region": { "startLine": 5, -"startColumn": 9, +"startColumn": 22, "endLine": 5, -"endColumn": 57 +"endColumn": 38 } } }, @@ -20,9 +20,9 @@ "uri": "sources\Net7\Net7\features\GenericAttributes.cs", "region": { "startLine": 10, -"startColumn": 9, -"endLine": 14, -"endColumn": 10 +"startColumn": 22, +"endLine": 10, +"endColumn": 33 } } }, @@ -33,9 +33,9 @@ "uri": "sources\Net7\Net7\features\RefFieldsAndRefScopedVariables.cs", "region": { "startLine": 5, -"startColumn": 9, -"endLine": 10, -"endColumn": 10 +"startColumn": 27, +"endLine": 5, +"endColumn": 36 } } }, @@ -46,9 +46,9 @@ "uri": "sources\Net7\Net7\features\RefFieldsAndRefScopedVariables.cs", "region": { "startLine": 13, -"startColumn": 9, -"endLine": 24, -"endColumn": 10 +"startColumn": 36, +"endLine": 13, +"endColumn": 53 } } }, @@ -59,9 +59,9 @@ "uri": "sources\Net7\Net7\features\WarningWave7.cs", "region": { "startLine": 5, -"startColumn": 9, -"endLine": 7, -"endColumn": 10 +"startColumn": 22, +"endLine": 5, +"endColumn": 35 } } } diff --git a/analyzers/its/expected/SkipGenerated.CS/SkipGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json b/analyzers/its/expected/SkipGenerated.CS/SkipGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json index 8832ac1eafa..98dea8cae89 100644 --- a/analyzers/its/expected/SkipGenerated.CS/SkipGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json +++ b/analyzers/its/expected/SkipGenerated.CS/SkipGeneratedFiles-6389f4a4-59fd-497b-bb52-4414b1320d29-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\GeneratedCode.CS\generated_region.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 21, +"endLine": 7, +"endColumn": 27 } } }, @@ -20,9 +20,9 @@ "uri": "sources\GeneratedCode.CS\generated_region_2.cs", "region": { "startLine": 7, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 21, +"endLine": 7, +"endColumn": 27 } } }, @@ -33,9 +33,9 @@ "uri": "sources\GeneratedCode.CS\handwritten.cs", "region": { "startLine": 8, -"startColumn": 9, -"endLine": 12, -"endColumn": 10 +"startColumn": 21, +"endLine": 8, +"endColumn": 27 } } }, @@ -46,9 +46,9 @@ "uri": "sources\GeneratedCode.CS\handwritten.cs", "region": { "startLine": 14, -"startColumn": 9, -"endLine": 16, -"endColumn": 10 +"startColumn": 22, +"endLine": 14, +"endColumn": 25 } } } diff --git a/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json index 25ede99f4dd..f0ef9dfeff4 100644 --- a/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka\Actor\Props.cs", "region": { "startLine": 683, -"startColumn": 9, -"endLine": 704, -"endColumn": 10 +"startColumn": 23, +"endLine": 683, +"endColumn": 38 } } }, @@ -189,9 +189,9 @@ "uri": "sources\akka.net\src\core\Akka\IO\UdpConnection.cs", "region": { "startLine": 245, -"startColumn": 9, -"endLine": 249, -"endColumn": 10 +"startColumn": 22, +"endLine": 245, +"endColumn": 31 } } }, @@ -215,9 +215,9 @@ "uri": "sources\akka.net\src\core\Akka\Util\MurmurHash.cs", "region": { "startLine": 155, -"startColumn": 9, -"endLine": 158, -"endColumn": 10 +"startColumn": 30, +"endLine": 155, +"endColumn": 42 } } }, diff --git a/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json b/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json index 3c6701de75e..e1cd90fd6d9 100644 --- a/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json @@ -33,9 +33,9 @@ "uri": "sources\akka.net\src\benchmark\Akka.Benchmarks\Cluster\ReachabilityBenchmarks.cs", "region": { "startLine": 84, -"startColumn": 9, -"endLine": 88, -"endColumn": 10 +"startColumn": 22, +"endLine": 84, +"endColumn": 33 } } }, diff --git a/analyzers/its/expected/akka.net/Akka.Cluster--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Cluster--netstandard2.0-S1144.json index 2c233f4835b..9e89cd76d2b 100644 --- a/analyzers/its/expected/akka.net/Akka.Cluster--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Cluster--netstandard2.0-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.Cluster\ClusterEvent.cs", "region": { "startLine": 1113, -"startColumn": 9, -"endLine": 1116, -"endColumn": 10 +"startColumn": 22, +"endLine": 1113, +"endColumn": 32 } } } diff --git a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net471-S1144.json b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net471-S1144.json index 49b0a09e614..f79599f97b2 100644 --- a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net471-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net471-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 469, -"startColumn": 9, -"endLine": 472, -"endColumn": 10 +"startColumn": 23, +"endLine": 469, +"endColumn": 44 } } }, @@ -33,9 +33,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 536, -"startColumn": 9, -"endLine": 539, -"endColumn": 10 +"startColumn": 29, +"endLine": 536, +"endColumn": 46 } } } diff --git a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net5.0-S1144.json b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net5.0-S1144.json index a167f6ab5ba..74212017ea0 100644 --- a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net5.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--net5.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 469, -"startColumn": 9, -"endLine": 472, -"endColumn": 10 +"startColumn": 23, +"endLine": 469, +"endColumn": 44 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 536, -"startColumn": 9, -"endLine": 539, -"endColumn": 10 +"startColumn": 29, +"endLine": 536, +"endColumn": 46 } } } diff --git a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--netcoreapp3.1-S1144.json b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--netcoreapp3.1-S1144.json index a167f6ab5ba..74212017ea0 100644 --- a/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--netcoreapp3.1-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.MultiNodeTestRunner--netcoreapp3.1-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 469, -"startColumn": 9, -"endLine": 472, -"endColumn": 10 +"startColumn": 23, +"endLine": 469, +"endColumn": 44 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.MultiNodeTestRunner\Program.cs", "region": { "startLine": 536, -"startColumn": 9, -"endLine": 539, -"endColumn": 10 +"startColumn": 29, +"endLine": 536, +"endColumn": 46 } } } diff --git a/analyzers/its/expected/akka.net/Akka.Persistence.Sql.Common--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Persistence.Sql.Common--netstandard2.0-S1144.json index 23fc49d228e..753561c1a77 100644 --- a/analyzers/its/expected/akka.net/Akka.Persistence.Sql.Common--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Persistence.Sql.Common--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\contrib\persistence\Akka.Persistence.Sql.Common\Journal\SqlJournal.cs", "region": { "startLine": 416, -"startColumn": 9, -"endLine": 424, -"endColumn": 10 +"startColumn": 34, +"endLine": 416, +"endColumn": 51 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\contrib\persistence\Akka.Persistence.Sql.Common\Snapshot\SqlSnapshotStore.cs", "region": { "startLine": 224, -"startColumn": 9, -"endLine": 239, -"endColumn": 10 +"startColumn": 31, +"endLine": 224, +"endColumn": 46 } } } diff --git a/analyzers/its/expected/akka.net/Akka.Persistence.TCK--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Persistence.TCK--netstandard2.0-S1144.json index 1842e209ab3..1452ea54e86 100644 --- a/analyzers/its/expected/akka.net/Akka.Persistence.TCK--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Persistence.TCK--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka.Persistence.TCK\Serialization\JournalSerializationSpec.cs", "region": { "startLine": 183, -"startColumn": 9, -"endLine": 217, -"endColumn": 10 +"startColumn": 22, +"endLine": 183, +"endColumn": 42 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.Persistence.TCK\Serialization\JournalSerializationSpec.cs", "region": { "startLine": 219, -"startColumn": 9, -"endLine": 236, -"endColumn": 10 +"startColumn": 22, +"endLine": 219, +"endColumn": 36 } } } diff --git a/analyzers/its/expected/akka.net/Akka.Remote--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Remote--netstandard2.0-S1144.json index ed99e1cc4b1..f6a9123a13a 100644 --- a/analyzers/its/expected/akka.net/Akka.Remote--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Remote--netstandard2.0-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.Remote\Transport\DotNetty\DotNettyTransport.cs", "region": { "startLine": 402, -"startColumn": 9, -"endLine": 408, -"endColumn": 10 +"startColumn": 40, +"endLine": 402, +"endColumn": 56 } } } diff --git a/analyzers/its/expected/akka.net/Akka.Streams--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Streams--netstandard2.0-S1144.json index 25a8647ad55..40a07b500bf 100644 --- a/analyzers/its/expected/akka.net/Akka.Streams--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Streams--netstandard2.0-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.Streams\Implementation\FanOut.cs", "region": { "startLine": 36, -"startColumn": 13, +"startColumn": 38, "endLine": 36, -"endColumn": 107 +"endColumn": 56 } } }, @@ -33,9 +33,9 @@ "uri": "sources\akka.net\src\core\Akka.Streams\Stage\GraphStage.cs", "region": { "startLine": 542, -"startColumn": 13, -"endLine": 554, -"endColumn": 14 +"startColumn": 26, +"endLine": 542, +"endColumn": 38 } } } diff --git a/analyzers/its/expected/akka.net/Akka.Streams.TestKit--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.Streams.TestKit--netstandard2.0-S1144.json index 0663794dfcc..da4e2034116 100644 --- a/analyzers/its/expected/akka.net/Akka.Streams.TestKit--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Streams.TestKit--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka.Streams.TestKit\TestSubscriber.cs", "region": { "startLine": 516, -"startColumn": 13, -"endLine": 519, -"endColumn": 14 +"startColumn": 26, +"endLine": 516, +"endColumn": 32 } } } diff --git a/analyzers/its/expected/akka.net/Akka.TestKit--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.TestKit--netstandard2.0-S1144.json index afd745c4195..36dbb980480 100644 --- a/analyzers/its/expected/akka.net/Akka.TestKit--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.TestKit--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\core\Akka.TestKit\DelegatingSupervisorStrategy.cs", "region": { "startLine": 48, -"startColumn": 9, -"endLine": 51, -"endColumn": 10 +"startColumn": 36, +"endLine": 48, +"endColumn": 44 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka.TestKit\Internal\BlockingQueue.cs", "region": { "startLine": 145, -"startColumn": 9, -"endLine": 246, -"endColumn": 10 +"startColumn": 23, +"endLine": 145, +"endColumn": 40 } } } From ca3a538f771c808073e442d12828858e1f74e051 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Fri, 27 Jan 2023 09:27:33 +0100 Subject: [PATCH 03/19] S1144 only highlights identifiers for every syntax node type --- .../Rules/UnusedPrivateMember.cs | 14 +++----------- .../Rules/UnusedPrivateMemberTest.Constructors.cs | 2 +- .../Rules/UnusedPrivateMemberTest.Properties.cs | 2 +- .../TestCases/UnusedPrivateMember.cs | 6 +++--- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index bcb53aad795..66fd9c1a4a6 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -42,14 +42,6 @@ public sealed class UnusedPrivateMember : SonarDiagnosticAnalyzer KnownType.UnityEngine_ScriptableObject, KnownType.Microsoft_EntityFrameworkCore_Migrations_Migration); - private static readonly SyntaxKind[] SyntaxKindsToOnlyShowIdentifierLocation = new[] - { - SyntaxKindEx.RecordClassDeclaration, - SyntaxKindEx.RecordStructDeclaration, - SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, - SyntaxKind.MethodDeclaration - }; - public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(RuleS1144, RuleS4487); protected override bool EnableConcurrentExecution => false; @@ -228,7 +220,7 @@ Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => } private static Location GetIssueLocation(SyntaxNode syntaxNode) => - syntaxNode.IsAnyKind(SyntaxKindsToOnlyShowIdentifierLocation) && syntaxNode.GetIdentifier().HasValue + syntaxNode.GetIdentifier().HasValue ? syntaxNode.GetIdentifier().Value.GetLocation() : syntaxNode.GetLocation(); @@ -239,14 +231,14 @@ private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IR && property.SetMethod is { } && GetAccessorSyntax(property.SetMethod) is { } setter) { - return Diagnostic.Create(RuleS1144, setter.GetLocation(), SyntaxConstants.Private, "set accessor in property", property.Name); + return Diagnostic.Create(RuleS1144, setter.Keyword.GetLocation(), SyntaxConstants.Private, "set accessor in property", property.Name); } else if (access == AccessorAccess.Set && property.GetMethod is { } && GetAccessorSyntax(property.GetMethod) is { } getter && getter.HasBodyOrExpressionBody()) { - return Diagnostic.Create(RuleS1144, getter.GetLocation(), SyntaxConstants.Private, "get accessor in property", property.Name); + return Diagnostic.Create(RuleS1144, getter.Keyword.GetLocation(), SyntaxConstants.Private, "get accessor in property", property.Name); } else { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Constructors.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Constructors.cs index 87ea5e7c288..f8eab73b67d 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Constructors.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Constructors.cs @@ -28,7 +28,7 @@ public void UnusedPrivateMember_Constructor_Accessibility() => public class PrivateConstructors { private PrivateConstructors(int i) { var x = 5; } // Noncompliant {{Remove the unused private constructor 'PrivateConstructors'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^^^^^^^^^^^^^^ static PrivateConstructors() { var x = 5; } private class InnerPrivateClass // Noncompliant diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Properties.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Properties.cs index 0aa7856881d..07f4130f496 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Properties.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnusedPrivateMemberTest.Properties.cs @@ -28,7 +28,7 @@ public void UnusedPrivateMember_Property_Accessibility() => public class PrivateMembers { private int PrivateProperty { get; set; } // Noncompliant {{Remove the unused private property 'PrivateProperty'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^^^^^^^^^^ private static int PrivateStaticProperty { get; set; } // Noncompliant private int this[string i] { get { return 5; } set { } } // Noncompliant diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index 7a5e3a8df42..f930485a893 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -223,12 +223,12 @@ private void MyOnClick(object sender, EventArgs args) { } // Compliant, event ha public class PropertyAccess { private int OnlyRead { get; set; } // Noncompliant {{Remove the unused private set accessor in property 'OnlyRead'.}} -// ^^^^ +// ^^^ private int OnlySet { get; set; } private int OnlySet2 { get { return 42; } set { } } // Noncompliant {{Remove the unused private get accessor in property 'OnlySet2'.}} -// ^^^^^^^^^^^^^^^^^^ +// ^^^ private int NotAccessed { get; set; } // Noncompliant {{Remove the unused private property 'NotAccessed'.}} -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// ^^^^^^^^^^^ private int BothAccessed { get; set; } private int OnlyGet { get { return 42; } } From 278440f1c1240fa3757b7b47c9cd521f6f1aaade Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Fri, 27 Jan 2023 09:38:10 +0100 Subject: [PATCH 04/19] Update sarif files again --- .../expected/Nancy/Nancy--net452-S1144.json | 6 ++-- .../Nancy/Nancy--netstandard2.0-S1144.json | 6 ++-- .../its/expected/Net5/Net5--net5.0-S1144.json | 30 ++++++++-------- ...leReferenceTypesExample--net6.0-S1144.json | 2 +- .../akka.net/Akka--netstandard2.0-S1144.json | 30 ++++++++-------- .../Akka.Benchmarks--netcoreapp3.1-S1144.json | 18 +++++----- ...Akka.DI.TestKit--netstandard2.0-S1144.json | 36 +++++++++---------- 7 files changed, 64 insertions(+), 64 deletions(-) diff --git a/analyzers/its/expected/Nancy/Nancy--net452-S1144.json b/analyzers/its/expected/Nancy/Nancy--net452-S1144.json index d3adb2f71fb..8c20a08a4f3 100644 --- a/analyzers/its/expected/Nancy/Nancy--net452-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy--net452-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\Nancy\src\Nancy\Conventions\StaticContentConventionBuilder.cs", "region": { "startLine": 277, -"startColumn": 13, -"endLine": 280, -"endColumn": 14 +"startColumn": 27, +"endLine": 277, +"endColumn": 35 } } }, diff --git a/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json b/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json index ae9d3681cc1..7c92e147539 100644 --- a/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json +++ b/analyzers/its/expected/Nancy/Nancy--netstandard2.0-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\Nancy\src\Nancy\Conventions\StaticContentConventionBuilder.cs", "region": { "startLine": 277, -"startColumn": 13, -"endLine": 280, -"endColumn": 14 +"startColumn": 27, +"endLine": 277, +"endColumn": 35 } } }, diff --git a/analyzers/its/expected/Net5/Net5--net5.0-S1144.json b/analyzers/its/expected/Net5/Net5--net5.0-S1144.json index d44c2b938f8..2c50045983a 100644 --- a/analyzers/its/expected/Net5/Net5--net5.0-S1144.json +++ b/analyzers/its/expected/Net5/Net5--net5.0-S1144.json @@ -59,9 +59,9 @@ "uri": "sources\Net5\Net5\S1144.cs", "region": { "startLine": 10, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 17, +"endLine": 10, +"endColumn": 22 } } }, @@ -255,8 +255,8 @@ "region": { "startLine": 7, "startColumn": 9, -"endLine": 17, -"endColumn": 10 +"endLine": 7, +"endColumn": 15 } } }, @@ -267,9 +267,9 @@ "uri": "sources\Net5\Net5\S3626.cs", "region": { "startLine": 5, -"startColumn": 9, -"endLine": 13, -"endColumn": 10 +"startColumn": 13, +"endLine": 5, +"endColumn": 17 } } }, @@ -280,9 +280,9 @@ "uri": "sources\Net5\Net5\S3776.cs", "region": { "startLine": 8, -"startColumn": 9, -"endLine": 21, -"endColumn": 10 +"startColumn": 16, +"endLine": 8, +"endColumn": 24 } } }, @@ -332,9 +332,9 @@ "uri": "sources\Net5\Net5\S4015.cs", "region": { "startLine": 7, -"startColumn": 13, +"startColumn": 24, "endLine": 7, -"endColumn": 47 +"endColumn": 32 } } }, @@ -358,9 +358,9 @@ "uri": "sources\Net5\Net5\S4015.cs", "region": { "startLine": 12, -"startColumn": 13, +"startColumn": 24, "endLine": 12, -"endColumn": 55 +"endColumn": 32 } } }, diff --git a/analyzers/its/expected/Net6/NullableReferenceTypesExample--net6.0-S1144.json b/analyzers/its/expected/Net6/NullableReferenceTypesExample--net6.0-S1144.json index 3e378a886ae..3fac7c477d4 100644 --- a/analyzers/its/expected/Net6/NullableReferenceTypesExample--net6.0-S1144.json +++ b/analyzers/its/expected/Net6/NullableReferenceTypesExample--net6.0-S1144.json @@ -9,7 +9,7 @@ "startLine": 5, "startColumn": 57, "endLine": 5, -"endColumn": 61 +"endColumn": 60 } } } diff --git a/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json index f0ef9dfeff4..44bf74d1156 100644 --- a/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka--netstandard2.0-S1144.json @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\core\Akka\Actor\Props.cs", "region": { "startLine": 687, -"startColumn": 13, -"endLine": 690, -"endColumn": 14 +"startColumn": 20, +"endLine": 687, +"endColumn": 35 } } }, @@ -85,9 +85,9 @@ "uri": "sources\akka.net\src\core\Akka\Event\DeadLetterListener.cs", "region": { "startLine": 240, -"startColumn": 13, +"startColumn": 25, "endLine": 240, -"endColumn": 63 +"endColumn": 36 } } }, @@ -98,9 +98,9 @@ "uri": "sources\akka.net\src\core\Akka\Event\DeadLetterListener.cs", "region": { "startLine": 255, -"startColumn": 13, +"startColumn": 29, "endLine": 255, -"endColumn": 80 +"endColumn": 37 } } }, @@ -137,9 +137,9 @@ "uri": "sources\akka.net\src\core\Akka\IO\Buffers\DirectBufferPool.cs", "region": { "startLine": 105, -"startColumn": 9, +"startColumn": 21, "endLine": 105, -"endColumn": 71 +"endColumn": 36 } } }, @@ -150,9 +150,9 @@ "uri": "sources\akka.net\src\core\Akka\IO\TcpConnection.cs", "region": { "startLine": 892, -"startColumn": 13, -"endLine": 896, -"endColumn": 14 +"startColumn": 20, +"endLine": 892, +"endColumn": 45 } } }, @@ -163,9 +163,9 @@ "uri": "sources\akka.net\src\core\Akka\IO\TcpConnection.cs", "region": { "startLine": 903, -"startColumn": 13, -"endLine": 906, -"endColumn": 14 +"startColumn": 20, +"endLine": 903, +"endColumn": 35 } } }, diff --git a/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json b/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json index e1cd90fd6d9..a46eff19cf0 100644 --- a/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.Benchmarks--netcoreapp3.1-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\benchmark\Akka.Benchmarks\Actor\SpawnActorBenchmarks.cs", "region": { "startLine": 72, -"startColumn": 13, -"endLine": 91, -"endColumn": 14 +"startColumn": 20, +"endLine": 72, +"endColumn": 26 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\benchmark\Akka.Benchmarks\Actor\SpawnActorBenchmarks.cs", "region": { "startLine": 97, -"startColumn": 13, -"endLine": 100, -"endColumn": 14 +"startColumn": 20, +"endLine": 97, +"endColumn": 25 } } }, @@ -46,9 +46,9 @@ "uri": "sources\akka.net\src\benchmark\Akka.Benchmarks\Serialization\SerializationBenchmarks.cs", "region": { "startLine": 54, -"startColumn": 13, -"endLine": 57, -"endColumn": 14 +"startColumn": 20, +"endLine": 54, +"endColumn": 24 } } } diff --git a/analyzers/its/expected/akka.net/Akka.DI.TestKit--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.DI.TestKit--netstandard2.0-S1144.json index 8a83aac165f..aed6c956e3a 100644 --- a/analyzers/its/expected/akka.net/Akka.DI.TestKit--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.DI.TestKit--netstandard2.0-S1144.json @@ -7,9 +7,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 34, -"startColumn": 13, -"endLine": 40, -"endColumn": 14 +"startColumn": 20, +"endLine": 34, +"endColumn": 37 } } }, @@ -20,9 +20,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 47, -"startColumn": 13, -"endLine": 53, -"endColumn": 14 +"startColumn": 20, +"endLine": 47, +"endColumn": 36 } } }, @@ -33,9 +33,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 62, -"startColumn": 13, -"endLine": 65, -"endColumn": 14 +"startColumn": 20, +"endLine": 62, +"endColumn": 33 } } }, @@ -46,9 +46,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 82, -"startColumn": 13, -"endLine": 88, -"endColumn": 14 +"startColumn": 20, +"endLine": 82, +"endColumn": 35 } } }, @@ -59,9 +59,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 170, -"startColumn": 13, -"endLine": 173, -"endColumn": 14 +"startColumn": 20, +"endLine": 170, +"endColumn": 39 } } }, @@ -72,9 +72,9 @@ "uri": "sources\akka.net\src\contrib\dependencyinjection\Akka.DI.TestKit\DiResolverSpec.cs", "region": { "startLine": 182, -"startColumn": 13, -"endLine": 185, -"endColumn": 14 +"startColumn": 20, +"endLine": 182, +"endColumn": 37 } } } From 97d5d4b2f200cd75cd90a72454bc2b52e1448bd2 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Wed, 1 Feb 2023 10:40:14 +0100 Subject: [PATCH 05/19] Refactor identifier locator method and test cases --- .../Rules/UnusedPrivateMember.cs | 12 ++++++------ .../TestCases/UnusedPrivateMember.CSharp10.cs | 2 ++ .../TestCases/UnusedPrivateMember.CSharp9.cs | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index 66fd9c1a4a6..82b4a78d33f 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -216,13 +216,13 @@ static IEnumerable GetSiblingDeclarators(SyntaxNode va }; Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => - Diagnostic.Create(RuleS1144, GetIssueLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); - } + Diagnostic.Create(RuleS1144, GetIdentifierLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); - private static Location GetIssueLocation(SyntaxNode syntaxNode) => - syntaxNode.GetIdentifier().HasValue - ? syntaxNode.GetIdentifier().Value.GetLocation() - : syntaxNode.GetLocation(); + static Location GetIdentifierLocation(SyntaxNode syntaxNode) => + syntaxNode.GetIdentifier().HasValue + ? syntaxNode.GetIdentifier().Value.GetLocation() + : syntaxNode.GetLocation(); + } private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IReadOnlyDictionary propertyAccessorAccess) { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs index 9bb69caff9d..debaaacfc52 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs @@ -38,6 +38,8 @@ public void UseNested2() } private record struct UnusedNested1(string Name, int CategoryId); // Noncompliant +// ^^^^^^^^^^^^^ + internal record struct UnusedNested2(string Name, int CategoryId); // Noncompliant public record struct UnusedNested3(string Name, int CategoryId); record struct UnusedNested4(string Name, int CategoryId); // Noncompliant diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp9.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp9.cs index e2b3542c09a..08b15600c71 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp9.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp9.cs @@ -36,6 +36,8 @@ public void UseNested2() } private record UnusedNested1(string Name, int CategoryId); // Noncompliant +// ^^^^^^^^^^^^^ + internal record UnusedNested2(string Name, int CategoryId); // Noncompliant public record UnusedNested3(string Name, int CategoryId); From cb675a1f61725084a4c56e2f8fcdda03c2f6841b Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Wed, 1 Feb 2023 10:55:24 +0100 Subject: [PATCH 06/19] Remove fading out of unused code --- .../src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index 82b4a78d33f..89982e184c5 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -using Microsoft.CodeAnalysis; using SonarAnalyzer.Constants; namespace SonarAnalyzer.Rules.CSharp @@ -32,7 +31,7 @@ public sealed class UnusedPrivateMember : SonarDiagnosticAnalyzer private const string S4487DiagnosticId = "S4487"; private const string S4487MessageFormat = "Remove this unread {0} field '{1}' or refactor the code to use its value."; - private static readonly DiagnosticDescriptor RuleS1144 = DescriptorFactory.Create(S1144DiagnosticId, S1144MessageFormat, fadeOutCode: true); + private static readonly DiagnosticDescriptor RuleS1144 = DescriptorFactory.Create(S1144DiagnosticId, S1144MessageFormat); private static readonly DiagnosticDescriptor RuleS4487 = DescriptorFactory.Create(S4487DiagnosticId, S4487MessageFormat, fadeOutCode: true); private static readonly ImmutableArray IgnoredTypes = ImmutableArray.Create( From 08b8d1f2dd3b9222bfca1fd0bf3b400e71e5e15a Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Wed, 1 Feb 2023 16:17:19 +0100 Subject: [PATCH 07/19] Remove fade out effect for S4487 --- analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index 89982e184c5..dd07f29dbfc 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -32,7 +32,7 @@ public sealed class UnusedPrivateMember : SonarDiagnosticAnalyzer private const string S4487MessageFormat = "Remove this unread {0} field '{1}' or refactor the code to use its value."; private static readonly DiagnosticDescriptor RuleS1144 = DescriptorFactory.Create(S1144DiagnosticId, S1144MessageFormat); - private static readonly DiagnosticDescriptor RuleS4487 = DescriptorFactory.Create(S4487DiagnosticId, S4487MessageFormat, fadeOutCode: true); + private static readonly DiagnosticDescriptor RuleS4487 = DescriptorFactory.Create(S4487DiagnosticId, S4487MessageFormat); private static readonly ImmutableArray IgnoredTypes = ImmutableArray.Create( KnownType.UnityEditor_AssetModificationProcessor, From 93f6c0d63fb5ea59654b5261070c34ae745b3c39 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Wed, 1 Feb 2023 17:04:19 +0100 Subject: [PATCH 08/19] Add FN test case for local functions --- .../TestCases/UnusedPrivateMember.Fixed.Batch.cs | 8 ++++++++ .../TestCases/UnusedPrivateMember.Fixed.cs | 8 ++++++++ .../TestCases/UnusedPrivateMember.cs | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index c0a402d53a6..34a77687d43 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -95,6 +95,14 @@ private interface MyInterface { void Method(); } + + public void MethodUsingLocalMethod() + { + void LocalMethod() // Compliant - FN: local function is never used + { + + } + } } class NewClass1 diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index ffebdae6fbe..c0c99663a2f 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -79,6 +79,14 @@ private int MyProperty [My] private class Class1 { } + + public void MethodUsingLocalMethod() + { + void LocalMethod() // Compliant - FN: local function is never used + { + + } + } } class NewClass1 diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index f930485a893..486923a34bc 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -145,6 +145,14 @@ internal class Class4 : MyInterface // Noncompliant {{Remove the unused internal { public void Method() { } } + + public void MethodUsingLocalMethod() + { + void LocalMethod() // Compliant - FN: local function is never used + { + + } + } } class NewClass1 @@ -229,6 +237,8 @@ public class PropertyAccess // ^^^ private int NotAccessed { get; set; } // Noncompliant {{Remove the unused private property 'NotAccessed'.}} // ^^^^^^^^^^^ + private int Calculated => 1; // Noncompliant {{Remove the unused private property 'Calculated'.}} +// ^^^^^^^^^^ private int BothAccessed { get; set; } private int OnlyGet { get { return 42; } } From 8bcab93f302e2eabe96cc9a89e364e39d825bee4 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Wed, 1 Feb 2023 17:40:07 +0100 Subject: [PATCH 09/19] Refactor GetIdentifierLocation --- .../src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index dd07f29dbfc..c9a00323f88 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -218,8 +218,8 @@ Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => Diagnostic.Create(RuleS1144, GetIdentifierLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); static Location GetIdentifierLocation(SyntaxNode syntaxNode) => - syntaxNode.GetIdentifier().HasValue - ? syntaxNode.GetIdentifier().Value.GetLocation() + syntaxNode.GetIdentifier() is { } identifier + ? identifier.GetLocation() : syntaxNode.GetLocation(); } From 9e31f17a985351afef477b94f0169f5e2a22bd49 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 11:02:15 +0100 Subject: [PATCH 10/19] Fix test case annotation --- .../TestCases/UnusedPrivateMember.Fixed.Batch.cs | 2 +- .../TestCases/UnusedPrivateMember.Fixed.cs | 2 +- .../SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index 34a77687d43..ea38d7527e5 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -98,7 +98,7 @@ private interface MyInterface public void MethodUsingLocalMethod() { - void LocalMethod() // Compliant - FN: local function is never used + void LocalMethod() // FN: local function is never used { } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index c0c99663a2f..489e28cd203 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -82,7 +82,7 @@ private class Class1 { } public void MethodUsingLocalMethod() { - void LocalMethod() // Compliant - FN: local function is never used + void LocalMethod() // FN: local function is never used { } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index 486923a34bc..ec2b36db7ec 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -148,7 +148,7 @@ public void Method() { } public void MethodUsingLocalMethod() { - void LocalMethod() // Compliant - FN: local function is never used + void LocalMethod() // FN: local function is never used { } From 66808e8357ef4897b93a55106f5bc046f0645149 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 11:03:08 +0100 Subject: [PATCH 11/19] Add GetIdentifier support for local functions --- analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs index f4854dc478a..8bdf052ba26 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs @@ -270,6 +270,7 @@ public static bool HasBodyOrExpressionBody(this AccessorDeclarationSyntax node) UsingDirectiveSyntax { Alias.Name: { } name } => GetIdentifier(name), VariableDeclaratorSyntax { Identifier: var identifier } => identifier, { } refType when RefTypeSyntaxWrapper.IsInstance(refType) => GetIdentifier(((RefTypeSyntaxWrapper)refType).Type), + { } localFunction when LocalFunctionStatementSyntaxWrapper.IsInstance(localFunction) => ((LocalFunctionStatementSyntaxWrapper)localFunction).Identifier, _ => null }; From b4f60b9b1d5e2f8cc19497f9c30d58ae09e30a29 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 12:05:18 +0100 Subject: [PATCH 12/19] Revert unintended change --- analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs index 8bdf052ba26..f4854dc478a 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs @@ -270,7 +270,6 @@ public static bool HasBodyOrExpressionBody(this AccessorDeclarationSyntax node) UsingDirectiveSyntax { Alias.Name: { } name } => GetIdentifier(name), VariableDeclaratorSyntax { Identifier: var identifier } => identifier, { } refType when RefTypeSyntaxWrapper.IsInstance(refType) => GetIdentifier(((RefTypeSyntaxWrapper)refType).Type), - { } localFunction when LocalFunctionStatementSyntaxWrapper.IsInstance(localFunction) => ((LocalFunctionStatementSyntaxWrapper)localFunction).Identifier, _ => null }; From aa46cfc446d32c277a9b4af772d2bb22df0625a0 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay <121798625+zsolt-kolbay-sonarsource@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:29:31 +0100 Subject: [PATCH 13/19] Update analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs Co-authored-by: Martin Strecker <103252490+martin-strecker-sonarsource@users.noreply.github.com> --- .../TestCases/UnusedPrivateMember.CSharp10.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs index debaaacfc52..7e1cee0fc40 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.CSharp10.cs @@ -39,7 +39,6 @@ public void UseNested2() private record struct UnusedNested1(string Name, int CategoryId); // Noncompliant // ^^^^^^^^^^^^^ - internal record struct UnusedNested2(string Name, int CategoryId); // Noncompliant public record struct UnusedNested3(string Name, int CategoryId); record struct UnusedNested4(string Name, int CategoryId); // Noncompliant From 22551a0851806b80b4bff368e2bc007f3c817e39 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 18:02:17 +0100 Subject: [PATCH 14/19] Updated GetIdentifierLocation for indexers --- .../Rules/UnusedPrivateMember.cs | 11 ++++++++-- .../UnusedPrivateMember.Fixed.Batch.cs | 16 ++++++++++++++ .../TestCases/UnusedPrivateMember.Fixed.cs | 16 ++++++++++++++ .../TestCases/UnusedPrivateMember.cs | 21 +++++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index c9a00323f88..8c4d72c1285 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -217,10 +217,17 @@ static IEnumerable GetSiblingDeclarators(SyntaxNode va Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => Diagnostic.Create(RuleS1144, GetIdentifierLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); - static Location GetIdentifierLocation(SyntaxNode syntaxNode) => - syntaxNode.GetIdentifier() is { } identifier + static Location GetIdentifierLocation(SyntaxNode syntaxNode) + { + if (syntaxNode is IndexerDeclarationSyntax indexer) + { + return indexer.ThisKeyword.GetLocation(); + } + + return syntaxNode.GetIdentifier() is { } identifier ? identifier.GetLocation() : syntaxNode.GetLocation(); + } } private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IReadOnlyDictionary propertyAccessorAccess) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index ea38d7527e5..0334c5c2cb6 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -193,6 +193,22 @@ public void M() } } + public class Indexer1 + { + } + + public class Indexer2 + { + } + + public class Indexer3 + { + } + + public class Indexer4 + { + } + [Serializable] public sealed class GoodException : Exception { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index 489e28cd203..02b7208e616 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -177,6 +177,22 @@ public void M() } } + public class Indexer1 + { + } + + public class Indexer2 + { + } + + public class Indexer3 + { + } + + public class Indexer4 + { + } + [Serializable] public sealed class GoodException : Exception { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index ec2b36db7ec..0674da716bb 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -256,6 +256,27 @@ public void M() } } + public class Indexer1 + { + private int this[int i] => 1; // Noncompliant +// ^^^^ + } + + public class Indexer2 + { + private int this[int i] { get => 1; } // Noncompliant + } + + public class Indexer3 + { + private int this[int i] { set => _ = value; } // Noncompliant + } + + public class Indexer4 + { + private int this[int i] { get { return 1; } set { _ = value; } } // Noncompliant + } + [Serializable] public sealed class GoodException : Exception { From 255e95c4f62722b8483d0991be4dfa8b7e94307f Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 18:27:51 +0100 Subject: [PATCH 15/19] Add more test cases for indexers --- .../UnusedPrivateMember.Fixed.Batch.cs | 20 ++++++++++++++++ .../TestCases/UnusedPrivateMember.Fixed.cs | 20 ++++++++++++++++ .../TestCases/UnusedPrivateMember.cs | 23 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index 0334c5c2cb6..f0e299b64f9 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -209,6 +209,26 @@ public class Indexer4 { } + public class Indexer5 + { + private int this[int i] { get { return 1; } } // Fixed + + public void Method() + { + Console.WriteLine(this[0]); + } + } + + public class Indexer6 + { + private int this[int i] { set { _ = value; } } // Fixed + + public void Method() + { + this[0] = 42; + } + } + [Serializable] public sealed class GoodException : Exception { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index 02b7208e616..1a490e50dd5 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -193,6 +193,26 @@ public class Indexer4 { } + public class Indexer5 + { + private int this[int i] { get { return 1; } } // Fixed + + public void Method() + { + Console.WriteLine(this[0]); + } + } + + public class Indexer6 + { + private int this[int i] { set { _ = value; } } // Fixed + + public void Method() + { + this[0] = 42; + } + } + [Serializable] public sealed class GoodException : Exception { diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index 0674da716bb..ceb0280e666 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -275,6 +275,29 @@ public class Indexer3 public class Indexer4 { private int this[int i] { get { return 1; } set { _ = value; } } // Noncompliant +// ^^^^ + } + + public class Indexer5 + { + private int this[int i] { get { return 1; } set { _ = value; } } // Noncompliant +// ^^^ + + public void Method() + { + Console.WriteLine(this[0]); + } + } + + public class Indexer6 + { + private int this[int i] { get { return 1; } set { _ = value; } } // Noncompliant +// ^^^ + + public void Method() + { + this[0] = 42; + } } [Serializable] From fff75ee64ecf919191a6db289cc2ee401d573bc2 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 19:17:39 +0100 Subject: [PATCH 16/19] Add test cases for expression bodies properties --- .../TestCases/UnusedPrivateMember.Fixed.Batch.cs | 6 ++++++ .../TestCases/UnusedPrivateMember.Fixed.cs | 6 ++++++ .../TestCases/UnusedPrivateMember.cs | 15 +++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index f0e299b64f9..3cc09868b5b 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -176,6 +176,9 @@ public class PropertyAccess private int OnlyRead { get; } // Fixed private int OnlySet { get; set; } private int OnlySet2 { set { } } // Fixed + private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed + private int ExpressionBodiedProperty6 { get => 1; } // Fixed + private int BothAccessed { get; set; } private int OnlyGet { get { return 42; } } @@ -190,6 +193,9 @@ public void M() int? x = 10; x = this?.OnlyGet; + + ExpressionBodiedProperty5 = 0; + Console.WriteLine(ExpressionBodiedProperty6); } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index 1a490e50dd5..50a34a65b04 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -160,6 +160,9 @@ public class PropertyAccess private int OnlyRead { get; } // Fixed private int OnlySet { get; set; } private int OnlySet2 { set { } } // Fixed + private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed + private int ExpressionBodiedProperty6 { get => 1; } // Fixed + private int BothAccessed { get; set; } private int OnlyGet { get { return 42; } } @@ -174,6 +177,9 @@ public void M() int? x = 10; x = this?.OnlyGet; + + ExpressionBodiedProperty5 = 0; + Console.WriteLine(ExpressionBodiedProperty6); } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index ceb0280e666..65e3729e399 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -237,8 +237,16 @@ public class PropertyAccess // ^^^ private int NotAccessed { get; set; } // Noncompliant {{Remove the unused private property 'NotAccessed'.}} // ^^^^^^^^^^^ - private int Calculated => 1; // Noncompliant {{Remove the unused private property 'Calculated'.}} -// ^^^^^^^^^^ + private int ExpressionBodiedProperty => 1; // Noncompliant {{Remove the unused private property 'ExpressionBodiedProperty'.}} +// ^^^^^^^^^^^^^^^^^^^^^^^^ + private int ExpressionBodiedProperty2 { get => 1; } // Noncompliant + private int ExpressionBodiedProperty3 { set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty4 { get => 1; set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty5 { get => 1; set => _ = value; } // Noncompliant +// ^^^ + private int ExpressionBodiedProperty6 { get => 1; set => _ = value; } // Noncompliant +// ^^^ + private int BothAccessed { get; set; } private int OnlyGet { get { return 42; } } @@ -253,6 +261,9 @@ public void M() int? x = 10; x = this?.OnlyGet; + + ExpressionBodiedProperty5 = 0; + Console.WriteLine(ExpressionBodiedProperty6); } } From 249ffb1888dd36fda082a2aa9e5b985ba74f341d Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Thu, 2 Feb 2023 20:13:47 +0100 Subject: [PATCH 17/19] Update sarif file --- .../Akka.DistributedData--netstandard2.0-S1144.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/analyzers/its/expected/akka.net/Akka.DistributedData--netstandard2.0-S1144.json b/analyzers/its/expected/akka.net/Akka.DistributedData--netstandard2.0-S1144.json index 789c576e0b0..511363de9a5 100644 --- a/analyzers/its/expected/akka.net/Akka.DistributedData--netstandard2.0-S1144.json +++ b/analyzers/its/expected/akka.net/Akka.DistributedData--netstandard2.0-S1144.json @@ -33,9 +33,9 @@ "uri": "sources\akka.net\src\contrib\cluster\Akka.DistributedData\Serialization\ReplicatorMessageSerializer.cs", "region": { "startLine": 56, -"startColumn": 13, -"endLine": 60, -"endColumn": 14 +"startColumn": 25, +"endLine": 56, +"endColumn": 29 } } } From 116828cd668f66ebc2e380e47624ed9a509e6377 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Mon, 6 Feb 2023 10:37:42 +0100 Subject: [PATCH 18/19] Add Indexer support to GetIdentifier method --- .../Helpers/CSharpSyntaxHelper.cs | 1 + .../SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs | 11 ++--------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs index f4854dc478a..8b30ece4ad5 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs @@ -249,6 +249,7 @@ public static bool HasBodyOrExpressionBody(this AccessorDeclarationSyntax node) DelegateDeclarationSyntax { Identifier: var identifier } => identifier, DestructorDeclarationSyntax { Identifier: var identifier } => identifier, EnumMemberDeclarationSyntax { Identifier: var identifier } => identifier, + IndexerDeclarationSyntax { ThisKeyword: var thisKeyword } => thisKeyword, InvocationExpressionSyntax { Expression: not InvocationExpressionSyntax // We don't want to recurse into nested invocations like: fun()() diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index 8c4d72c1285..c9a00323f88 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -217,17 +217,10 @@ static IEnumerable GetSiblingDeclarators(SyntaxNode va Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => Diagnostic.Create(RuleS1144, GetIdentifierLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); - static Location GetIdentifierLocation(SyntaxNode syntaxNode) - { - if (syntaxNode is IndexerDeclarationSyntax indexer) - { - return indexer.ThisKeyword.GetLocation(); - } - - return syntaxNode.GetIdentifier() is { } identifier + static Location GetIdentifierLocation(SyntaxNode syntaxNode) => + syntaxNode.GetIdentifier() is { } identifier ? identifier.GetLocation() : syntaxNode.GetLocation(); - } } private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IReadOnlyDictionary propertyAccessorAccess) From e4a8992ff11b231714c12ee7f4e02dae4fe775d5 Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Mon, 6 Feb 2023 10:42:51 +0100 Subject: [PATCH 19/19] Add test cases for FN --- .../UnusedPrivateMember.Fixed.Batch.cs | 12 ++++++---- .../TestCases/UnusedPrivateMember.Fixed.cs | 12 ++++++---- .../TestCases/UnusedPrivateMember.cs | 23 +++++++++++-------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs index 3cc09868b5b..40c567878a8 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.Batch.cs @@ -173,11 +173,15 @@ private void MyOnClick(object sender, EventArgs args) { } // Compliant, event ha public class PropertyAccess { - private int OnlyRead { get; } // Fixed + private int OnlyRead { get; } // Fixed private int OnlySet { get; set; } - private int OnlySet2 { set { } } // Fixed - private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed - private int ExpressionBodiedProperty6 { get => 1; } // Fixed + private int OnlySet2 { set { } } // Fixed + public int PrivateGetter { private get; set; } // FN - unused private getter + public int PrivateSetter { get; private set; } // FN - unused private setter + private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed + private int ExpressionBodiedProperty6 { get => 1; } // Fixed + public int ExpressionBodiedProperty7 { private get => 1; set => _ = value; } // FN - unused private getter + public int ExpressionBodiedProperty8 { get => 1; private set => _ = value; } // FN - unused private setter private int BothAccessed { get; set; } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs index 50a34a65b04..fec15f7cb0c 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.Fixed.cs @@ -157,11 +157,15 @@ private void MyOnClick(object sender, EventArgs args) { } // Compliant, event ha public class PropertyAccess { - private int OnlyRead { get; } // Fixed + private int OnlyRead { get; } // Fixed private int OnlySet { get; set; } - private int OnlySet2 { set { } } // Fixed - private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed - private int ExpressionBodiedProperty6 { get => 1; } // Fixed + private int OnlySet2 { set { } } // Fixed + public int PrivateGetter { private get; set; } // FN - unused private getter + public int PrivateSetter { get; private set; } // FN - unused private setter + private int ExpressionBodiedProperty5 { set => _ = value; } // Fixed + private int ExpressionBodiedProperty6 { get => 1; } // Fixed + public int ExpressionBodiedProperty7 { private get => 1; set => _ = value; } // FN - unused private getter + public int ExpressionBodiedProperty8 { get => 1; private set => _ = value; } // FN - unused private setter private int BothAccessed { get; set; } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs index 65e3729e399..be4364a7d8f 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/UnusedPrivateMember.cs @@ -230,22 +230,27 @@ private void MyOnClick(object sender, EventArgs args) { } // Compliant, event ha public class PropertyAccess { - private int OnlyRead { get; set; } // Noncompliant {{Remove the unused private set accessor in property 'OnlyRead'.}} + private int OnlyRead { get; set; } // Noncompliant {{Remove the unused private set accessor in property 'OnlyRead'.}} // ^^^ private int OnlySet { get; set; } - private int OnlySet2 { get { return 42; } set { } } // Noncompliant {{Remove the unused private get accessor in property 'OnlySet2'.}} + private int OnlySet2 { get { return 42; } set { } } // Noncompliant {{Remove the unused private get accessor in property 'OnlySet2'.}} // ^^^ - private int NotAccessed { get; set; } // Noncompliant {{Remove the unused private property 'NotAccessed'.}} + private int NotAccessed { get; set; } // Noncompliant {{Remove the unused private property 'NotAccessed'.}} // ^^^^^^^^^^^ - private int ExpressionBodiedProperty => 1; // Noncompliant {{Remove the unused private property 'ExpressionBodiedProperty'.}} + public int PrivateGetter { private get; set; } // FN - unused private getter + public int PrivateSetter { get; private set; } // FN - unused private setter + + private int ExpressionBodiedProperty => 1; // Noncompliant {{Remove the unused private property 'ExpressionBodiedProperty'.}} // ^^^^^^^^^^^^^^^^^^^^^^^^ - private int ExpressionBodiedProperty2 { get => 1; } // Noncompliant - private int ExpressionBodiedProperty3 { set => _ = value; } // Noncompliant - private int ExpressionBodiedProperty4 { get => 1; set => _ = value; } // Noncompliant - private int ExpressionBodiedProperty5 { get => 1; set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty2 { get => 1; } // Noncompliant + private int ExpressionBodiedProperty3 { set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty4 { get => 1; set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty5 { get => 1; set => _ = value; } // Noncompliant // ^^^ - private int ExpressionBodiedProperty6 { get => 1; set => _ = value; } // Noncompliant + private int ExpressionBodiedProperty6 { get => 1; set => _ = value; } // Noncompliant // ^^^ + public int ExpressionBodiedProperty7 { private get => 1; set => _ = value; } // FN - unused private getter + public int ExpressionBodiedProperty8 { get => 1; private set => _ = value; } // FN - unused private setter private int BothAccessed { get; set; }