From 1a3c72720ff8d31f76caba0d584af85005351551 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 25 Apr 2022 14:15:40 +0200 Subject: [PATCH 01/10] Use IsRedundantPositionalRecordContext --- .../Rules/PropertiesShouldBePreferred.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs index 9b709440f22..7fe3bec76de 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs @@ -24,6 +24,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; +using SonarAnalyzer.Extensions; using SonarAnalyzer.Helpers; using StyleCop.Analyzers.Lightup; @@ -40,11 +41,10 @@ public sealed class PropertiesShouldBePreferred : SonarDiagnosticAnalyzer public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule); protected override void Initialize(SonarAnalysisContext context) => - context.RegisterSyntaxNodeActionInNonGenerated( - c => + context.RegisterSyntaxNodeActionInNonGenerated(c => { - if (c.ContainingSymbol.Kind != SymbolKind.NamedType - || !(c.SemanticModel.GetDeclaredSymbol(c.Node) is INamedTypeSymbol typeSymbol)) + if (c.IsRedundantPositionalRecordContext() + || c.SemanticModel.GetDeclaredSymbol(c.Node) is not INamedTypeSymbol typeSymbol) { return; } From 4ca5b8f1ef1324b413cd1a31087871e86e54fccf Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 25 Apr 2022 14:35:37 +0200 Subject: [PATCH 02/10] Use VerifyerBuilder --- .../Rules/PropertiesShouldBePreferredTest.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs index 3d8dac80b2e..d1ddffe2ebe 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs @@ -28,24 +28,27 @@ namespace SonarAnalyzer.UnitTest.Rules [TestClass] public class PropertiesShouldBePreferredTest { + private readonly VerifierBuilder builder = new VerifierBuilder().AddReferences(MetadataReferenceFacade.SystemThreadingTasks); + [TestMethod] public void PropertiesShouldBePreferred() => - OldVerifier.VerifyAnalyzer(@"TestCases\PropertiesShouldBePreferred.cs", - new PropertiesShouldBePreferred(), - MetadataReferenceFacade.SystemThreadingTasks); + builder.AddPaths("PropertiesShouldBePreferred.cs").Verify(); #if NET + [TestMethod] public void PropertiesShouldBePreferred_CSharp9() => - OldVerifier.VerifyAnalyzerFromCSharp9Library(@"TestCases\PropertiesShouldBePreferred.CSharp9.cs", new PropertiesShouldBePreferred()); + builder.AddPaths("PropertiesShouldBePreferred.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify(); [TestMethod] public void PropertiesShouldBePreferred_CSharp10() => - OldVerifier.VerifyAnalyzerFromCSharp10Library(@"TestCases\PropertiesShouldBePreferred.CSharp10.cs", new PropertiesShouldBePreferred()); + builder.AddPaths("PropertiesShouldBePreferred.CSharp10.cs").WithOptions(ParseOptionsHelper.FromCSharp10).Verify(); [TestMethod] public void PropertiesShouldBePreferred_CSharpPreview() => - OldVerifier.VerifyAnalyzerCSharpPreviewLibrary(@"TestCases\PropertiesShouldBePreferred.CSharpPreview.cs", new PropertiesShouldBePreferred()); + builder.AddPaths("PropertiesShouldBePreferred.CSharpPreview.cs").WithOptions(ParseOptionsHelper.CSharpPreview).Verify(); + #endif + } } From dc6a9ce87ae0fe266272c2445ae63444bf1d69c7 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 25 Apr 2022 14:36:02 +0200 Subject: [PATCH 03/10] Add RecordStructDeclaration and some refactorings --- .../Rules/PropertiesShouldBePreferred.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs index 7fe3bec76de..970fab6ada9 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs @@ -19,8 +19,10 @@ */ using System; +using System.Collections; using System.Collections.Immutable; using System.Linq; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; @@ -67,7 +69,8 @@ protected override void Initialize(SonarAnalysisContext context) => }, SyntaxKind.ClassDeclaration, SyntaxKind.InterfaceDeclaration, - SyntaxKindEx.RecordClassDeclaration); + SyntaxKindEx.RecordClassDeclaration, + SyntaxKindEx.RecordStructDeclaration); private static bool HasCandidateSignature(IMethodSymbol method) => method.IsPubliclyAccessible() @@ -85,7 +88,7 @@ private static bool HasCandidateReturnType(IMethodSymbol method) => private static bool HasCandidateName(IMethodSymbol method) { - if (method.Name == "GetEnumerator" || method.Name == "GetAwaiter") + if (method.Name is nameof(IEnumerable.GetEnumerator) or nameof(Task.GetAwaiter)) { return false; } From 7233423636f5465907f8f0dcc86178846b3f839e Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 25 Apr 2022 14:36:13 +0200 Subject: [PATCH 04/10] Fix C# 10 tests --- .../Helpers/StringExtensions.cs | 16 +++++++++------- .../PropertiesShouldBePreferred.CSharp10.cs | 13 +++++-------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs b/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs index e6d9ecd9139..6f00788bc1d 100644 --- a/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs +++ b/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs @@ -31,15 +31,17 @@ public static class StringExtensions /// Sequence of upper case letters is considered as single word. /// /// For example: - /// thisIsAName => this is a name - /// ThisIsSMTPName => this is smtp name - /// bin2hex => bin hex - /// HTML => html - /// SOME_value => some value - /// PEHeader => pe header + /// + /// "thisIsAName" => ["THIS", "IS", "A", "NAME"] + /// "ThisIsSMTPName" => ["THIS", "IS", "SMTP", "NAME"] + /// "bin2hex" => ["BIN", "HEX"] + /// "HTML" => ["HTML"] + /// "SOME_value" => ["SOME", "VALUE"] + /// "PEHeader" => ["PE", "HEADER"] + /// /// /// A string containing words. - /// A list of words (all lowercase) contained in the string. + /// A list of words (all uppercase) contained in the string. public static IEnumerable SplitCamelCaseToWords(this string name) { bool IsFollowedByLower(int i) => i + 1 < name.Length && char.IsLower(name[i + 1]); diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.CSharp10.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.CSharp10.cs index 96ec882396c..9b136db669d 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.CSharp10.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.CSharp10.cs @@ -2,15 +2,14 @@ { private string name = ""; - public string GetName() // FN + public string GetName() // Noncompliant {{Consider making method 'GetName' a property.}} + // ^^^^^^^ { return name; } - public object GetName2() => null; // FN - + public object GetName2() => null; // Noncompliant private string GetName3() => null; // Compliant - public string Property { get; set; } = ""; } @@ -18,14 +17,12 @@ public record struct PositionalRecordStruct(string Parameter) { private string name = ""; - public string GetName() // FN + public string GetName() // Noncompliant { return name; } - public object GetName2() => null; // FN - + public object GetName2() => null; // Noncompliant private string GetName3() => null; // Compliant - public string Property { get; set; } = ""; } From 85f75b42ec9089f50eb0202999be753a8d1484b2 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 27 Apr 2022 11:33:35 +0200 Subject: [PATCH 05/10] Tests: Add reference to Tasks ony if needed by test --- .../Rules/PropertiesShouldBePreferredTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs index d1ddffe2ebe..20b5e865474 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/PropertiesShouldBePreferredTest.cs @@ -28,11 +28,11 @@ namespace SonarAnalyzer.UnitTest.Rules [TestClass] public class PropertiesShouldBePreferredTest { - private readonly VerifierBuilder builder = new VerifierBuilder().AddReferences(MetadataReferenceFacade.SystemThreadingTasks); + private readonly VerifierBuilder builder = new VerifierBuilder(); [TestMethod] public void PropertiesShouldBePreferred() => - builder.AddPaths("PropertiesShouldBePreferred.cs").Verify(); + builder.AddPaths("PropertiesShouldBePreferred.cs").AddReferences(MetadataReferenceFacade.SystemThreadingTasks).Verify(); #if NET From 84b17fc1e88b546000641cc41797dc482bd5d57a Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 27 Apr 2022 11:50:42 +0200 Subject: [PATCH 06/10] Merge the two implementations of SplitCamelCaseToWords --- .../CfgSerializer.SonarCfgWalker.cs | 2 +- .../Helpers/StringExtensions.cs | 18 ++-- .../Helpers/StringExtensions.cs | 90 ------------------- 3 files changed, 11 insertions(+), 99 deletions(-) delete mode 100644 analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs diff --git a/analyzers/src/SonarAnalyzer.CFG/CfgSerializer/CfgSerializer.SonarCfgWalker.cs b/analyzers/src/SonarAnalyzer.CFG/CfgSerializer/CfgSerializer.SonarCfgWalker.cs index 5e3667317bf..00070d13930 100644 --- a/analyzers/src/SonarAnalyzer.CFG/CfgSerializer/CfgSerializer.SonarCfgWalker.cs +++ b/analyzers/src/SonarAnalyzer.CFG/CfgSerializer/CfgSerializer.SonarCfgWalker.cs @@ -21,8 +21,8 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using SonarAnalyzer.CFG.Helpers; using SonarAnalyzer.CFG.Sonar; +using SonarAnalyzer.Helpers; namespace SonarAnalyzer.CFG { diff --git a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs index ba0bd801136..6d4e2c4c00b 100644 --- a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs +++ b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs @@ -21,7 +21,7 @@ using System.Collections.Generic; using System.Text; -namespace SonarAnalyzer.CFG.Helpers +namespace SonarAnalyzer.Helpers { public static class StringExtensions { @@ -31,15 +31,17 @@ public static class StringExtensions /// Sequence of upper case letters is considered as single word. /// /// For example: - /// thisIsAName => this is a name - /// ThisIsSMTPName => this is smtp name - /// bin2hex => bin hex - /// HTML => html - /// SOME_value => some value - /// PEHeader => pe header + /// + /// thisIsAName => ["THIS", "IS", "A", "NAME"] + /// ThisIsSMTPName => ["THIS", "IS", "SMTP", "NAME"] + /// bin2hex => ["BIN", "HEX"] + /// HTML => ["HTML"] + /// SOME_value => ["SOME", "VALUE"] + /// PEHeader => ["PE", "HEADER"] + /// /// /// A string containing words. - /// A list of words (all lowercase) contained in the string. + /// A list of words (all uppercase) contained in the string. public static IEnumerable SplitCamelCaseToWords(this string name) { bool IsFollowedByLower(int i) => i + 1 < name.Length && char.IsLower(name[i + 1]); diff --git a/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs b/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs deleted file mode 100644 index 6f00788bc1d..00000000000 --- a/analyzers/src/SonarAnalyzer.Common/Helpers/StringExtensions.cs +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SonarAnalyzer for .NET - * Copyright (C) 2015-2022 SonarSource SA - * mailto: contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -using System.Collections.Generic; -using System.Text; - -namespace SonarAnalyzer.Helpers -{ - public static class StringExtensions - { - /// - /// Splits the input string to the list of words. - /// - /// Sequence of upper case letters is considered as single word. - /// - /// For example: - /// - /// "thisIsAName" => ["THIS", "IS", "A", "NAME"] - /// "ThisIsSMTPName" => ["THIS", "IS", "SMTP", "NAME"] - /// "bin2hex" => ["BIN", "HEX"] - /// "HTML" => ["HTML"] - /// "SOME_value" => ["SOME", "VALUE"] - /// "PEHeader" => ["PE", "HEADER"] - /// - /// - /// A string containing words. - /// A list of words (all uppercase) contained in the string. - public static IEnumerable SplitCamelCaseToWords(this string name) - { - bool IsFollowedByLower(int i) => i + 1 < name.Length && char.IsLower(name[i + 1]); - - if (name == null) - { - yield break; - } - - var currentWord = new StringBuilder(); - var hasLower = false; - - for (var i = 0; i < name.Length; i++) - { - var c = name[i]; - if (!char.IsLetter(c)) - { - if (currentWord.Length > 0) - { - yield return currentWord.ToString(); - currentWord.Clear(); - hasLower = false; - } - continue; - } - - if (char.IsUpper(c) - && currentWord.Length > 0 - && (hasLower || IsFollowedByLower(i))) - { - yield return currentWord.ToString(); - currentWord.Clear(); - hasLower = false; - } - - currentWord.Append(char.ToUpperInvariant(c)); - hasLower = hasLower || char.IsLower(c); - } - - if (currentWord.Length > 0) - { - yield return currentWord.ToString(); - } - } - } -} From 94fbd1b362f35f1226a152ffd67509c31bbf9948 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 27 Apr 2022 11:55:47 +0200 Subject: [PATCH 07/10] Add support for structs --- .../Rules/PropertiesShouldBePreferred.cs | 6 ++---- .../TestCases/PropertiesShouldBePreferred.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs index 970fab6ada9..1d5a5d09f1b 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/PropertiesShouldBePreferred.cs @@ -54,10 +54,7 @@ protected override void Initialize(SonarAnalysisContext context) => var propertyCandidates = typeSymbol .GetMembers() .OfType() - .Where(HasCandidateName) - .Where(HasCandidateReturnType) - .Where(HasCandidateSignature) - .Where(UsageAttributesAllowProperties); + .Where(x => HasCandidateName(x) && HasCandidateReturnType(x) && HasCandidateSignature(x) && UsageAttributesAllowProperties(x)); foreach (var candidate in propertyCandidates) { @@ -69,6 +66,7 @@ protected override void Initialize(SonarAnalysisContext context) => }, SyntaxKind.ClassDeclaration, SyntaxKind.InterfaceDeclaration, + SyntaxKind.StructDeclaration, SyntaxKindEx.RecordClassDeclaration, SyntaxKindEx.RecordStructDeclaration); diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.cs index 150eaefa95a..d1f0628e1d2 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/PropertiesShouldBePreferred.cs @@ -62,7 +62,7 @@ public interface IBase public struct SomeStruct { - string GetStuff() { return ""; } // FN + public string GetStuff() { return ""; } // Noncompliant } public interface IFoo From 2a290b4d70272c9b1d0af8ef71e9a7a46e606751 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 27 Apr 2022 12:00:29 +0200 Subject: [PATCH 08/10] Small improvements in SplitCamelCaseToWords --- analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs index 6d4e2c4c00b..957cfb22fcd 100644 --- a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs +++ b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs @@ -44,14 +44,12 @@ public static class StringExtensions /// A list of words (all uppercase) contained in the string. public static IEnumerable SplitCamelCaseToWords(this string name) { - bool IsFollowedByLower(int i) => i + 1 < name.Length && char.IsLower(name[i + 1]); - if (name == null) { yield break; } - var currentWord = new StringBuilder(); + var currentWord = new StringBuilder(capacity: name.Length); var hasLower = false; for (var i = 0; i < name.Length; i++) @@ -85,6 +83,8 @@ public static IEnumerable SplitCamelCaseToWords(this string name) { yield return currentWord.ToString(); } + + bool IsFollowedByLower(int i) => i + 1 < name.Length && char.IsLower(name[i + 1]); } } } From a6b3d6667b008cbc14fe87b30f1946afa90e687b Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 2 May 2022 11:59:54 +0200 Subject: [PATCH 09/10] Update ITs --- .../Automapper/AutoMapper--net461-S4049.json | 13 +++++++++++++ .../AutoMapper--netstandard2.0-S4049.json | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/analyzers/its/expected/Automapper/AutoMapper--net461-S4049.json b/analyzers/its/expected/Automapper/AutoMapper--net461-S4049.json index 29d4b09afa3..230caa8fb48 100644 --- a/analyzers/its/expected/Automapper/AutoMapper--net461-S4049.json +++ b/analyzers/its/expected/Automapper/AutoMapper--net461-S4049.json @@ -41,6 +41,19 @@ }, { "id": "S4049", +"message": "Consider making method 'GetTypeDefinitionIfGeneric' a property.", +"location": { +"uri": "sources\Automapper\src\AutoMapper\Internal\TypePair.cs", +"region": { +"startLine": 56, +"startColumn": 25, +"endLine": 56, +"endColumn": 51 +} +} +}, +{ +"id": "S4049", "message": "Consider making method 'GetCurrentPath' a property.", "location": { "uri": "sources\Automapper\src\AutoMapper\QueryableExtensions\ProjectionBuilder.cs", diff --git a/analyzers/its/expected/Automapper/AutoMapper--netstandard2.0-S4049.json b/analyzers/its/expected/Automapper/AutoMapper--netstandard2.0-S4049.json index 29d4b09afa3..230caa8fb48 100644 --- a/analyzers/its/expected/Automapper/AutoMapper--netstandard2.0-S4049.json +++ b/analyzers/its/expected/Automapper/AutoMapper--netstandard2.0-S4049.json @@ -41,6 +41,19 @@ }, { "id": "S4049", +"message": "Consider making method 'GetTypeDefinitionIfGeneric' a property.", +"location": { +"uri": "sources\Automapper\src\AutoMapper\Internal\TypePair.cs", +"region": { +"startLine": 56, +"startColumn": 25, +"endLine": 56, +"endColumn": 51 +} +} +}, +{ +"id": "S4049", "message": "Consider making method 'GetCurrentPath' a property.", "location": { "uri": "sources\Automapper\src\AutoMapper\QueryableExtensions\ProjectionBuilder.cs", From 392e29898be83731dafa97c801c0cf399674bf39 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Tue, 3 May 2022 10:08:48 +0200 Subject: [PATCH 10/10] Remove capacity argument from sb --- analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs index 957cfb22fcd..cac7ca56a53 100644 --- a/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs +++ b/analyzers/src/SonarAnalyzer.CFG/Helpers/StringExtensions.cs @@ -49,7 +49,7 @@ public static IEnumerable SplitCamelCaseToWords(this string name) yield break; } - var currentWord = new StringBuilder(capacity: name.Length); + var currentWord = new StringBuilder(); var hasLower = false; for (var i = 0; i < name.Length; i++)