From dfbbe60de37fb33b6321a83a870f048db4e1f6a6 Mon Sep 17 00:00:00 2001 From: Costin Zaharia Date: Mon, 14 Mar 2022 10:36:45 +0100 Subject: [PATCH] Add repro for #5457 --- ...ExtensionMethodShouldBeInSeparateNamespace.cs | 10 +++------- ...nsionMethodShouldBeInSeparateNamespaceTest.cs | 16 +++++++++++++--- ...dShouldBeInSeparateNamespace.GeneratedCode.cs | 4 ++++ ...ExtensionMethodShouldBeInSeparateNamespace.cs | 5 +++++ 4 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.GeneratedCode.cs diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/ExtensionMethodShouldBeInSeparateNamespace.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/ExtensionMethodShouldBeInSeparateNamespace.cs index 5afec4ae3be..65c37969725 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/ExtensionMethodShouldBeInSeparateNamespace.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/ExtensionMethodShouldBeInSeparateNamespace.cs @@ -32,11 +32,9 @@ namespace SonarAnalyzer.Rules.CSharp public sealed class ExtensionMethodShouldBeInSeparateNamespace : SonarDiagnosticAnalyzer { private const string DiagnosticId = "S4226"; - private const string MessageFormat = "Either move this extension to another namespace or move the method " + - "inside the class itself."; + private const string MessageFormat = "Either move this extension to another namespace or move the method inside the class itself."; - private static readonly DiagnosticDescriptor Rule = - DiagnosticDescriptorBuilder.GetDescriptor(DiagnosticId, MessageFormat, RspecStrings.ResourceManager); + private static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorBuilder.GetDescriptor(DiagnosticId, MessageFormat, RspecStrings.ResourceManager); public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule); protected override void Initialize(SonarAnalysisContext context) => @@ -46,9 +44,7 @@ protected override void Initialize(SonarAnalysisContext context) => var methodDeclaration = (MethodDeclarationSyntax)c.Node; if (methodDeclaration.IsExtensionMethod() - && c.SemanticModel.GetDeclaredSymbol(methodDeclaration) is { } methodSymbol - && methodSymbol.IsExtensionMethod - && methodSymbol.Parameters.Length > 0 + && c.SemanticModel.GetDeclaredSymbol(methodDeclaration) is { IsExtensionMethod: true, Parameters: { Length: > 0 } } methodSymbol && methodSymbol.Parameters[0].Type.Kind != SymbolKind.ErrorType && methodSymbol.Parameters[0].Type.IsClass() && methodSymbol.ContainingNamespace.Equals(methodSymbol.Parameters[0].Type.ContainingNamespace)) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs index 8d5e38a859c..7219c70007d 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs @@ -27,19 +27,29 @@ namespace SonarAnalyzer.UnitTest.Rules [TestClass] public class ExtensionMethodShouldBeInSeparateNamespaceTest { + private readonly VerifierBuilder builder = new VerifierBuilder(); + [TestMethod] public void ExtensionMethodShouldBeInSeparateNamespace() => - OldVerifier.VerifyAnalyzer(@"TestCases\ExtensionMethodShouldBeInSeparateNamespace.cs", new ExtensionMethodShouldBeInSeparateNamespace()); + builder + .AddPaths("ExtensionMethodShouldBeInSeparateNamespace.cs", "ExtensionMethodShouldBeInSeparateNamespace.GeneratedCode.cs") + .Verify(); #if NET + [TestMethod] public void ExtensionMethodShouldBeInSeparateNamespace_CSharp9() => - OldVerifier.VerifyAnalyzerFromCSharp9Console(@"TestCases\ExtensionMethodShouldBeInSeparateNamespace.CSharp9.cs", new ExtensionMethodShouldBeInSeparateNamespace()); + builder.AddPaths("ExtensionMethodShouldBeInSeparateNamespace.CSharp9.cs").WithTopLevelStatements().Verify(); [TestMethod] public void ExtensionMethodShouldBeInSeparateNamespace_CSharp10() => - OldVerifier.VerifyAnalyzerFromCSharp10Library(@"TestCases\ExtensionMethodShouldBeInSeparateNamespace.CSharp10.cs", new ExtensionMethodShouldBeInSeparateNamespace()); + builder + .AddPaths("ExtensionMethodShouldBeInSeparateNamespace.CSharp10.cs") + .WithConcurrentAnalysis(false) + .WithOptions(ParseOptionsHelper.FromCSharp10) + .Verify(); #endif + } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.GeneratedCode.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.GeneratedCode.cs new file mode 100644 index 00000000000..a0f3e7ab0f2 --- /dev/null +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.GeneratedCode.cs @@ -0,0 +1,4 @@ +[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")] +public abstract partial class GenClass +{ +} diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.cs index 34cecaaf7b8..9f25b4bda49 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/ExtensionMethodShouldBeInSeparateNamespace.cs @@ -106,3 +106,8 @@ public static T FooGeneric(this T foo) // Compliant } } + +internal static class GenClassExtensions +{ + public static void SetSyncLaterError(this GenClass foo) { } // Noncompliant - FP, see: https://github.com/SonarSource/sonar-dotnet/issues/5457 +}