From 5aafbdcc922e5c2614cf067ad3af99477f5907d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Hellander?= Date: Sat, 22 Oct 2022 09:07:08 +0200 Subject: [PATCH] Update SA1313 to also allow incorrect names in explicitly implemented methods from interfaces #3555 --- .../NamingRules/SA1313UnitTests.cs | 51 +++++++++++++++++++ ...ameterNamesMustBeginWithLowerCaseLetter.cs | 13 ++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1313UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1313UnitTests.cs index b58eb28b9..216a0e9b8 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1313UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1313UnitTests.cs @@ -277,6 +277,57 @@ public void Method(int Param1, int param2, int Other) await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } + [Fact] + [WorkItem(3555, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3555")] + public async Task TestNoViolationOnExplicitlyImplementedInterfaceParameterNameAsync() + { + var testCode = @" +public interface ITest +{ + void Method(int param1, int {|#0:Param2|}); +} + +public class Test : ITest +{ + void ITest.Method(int param1, int Param2) + { + } +}"; + + var expected = new[] + { + Diagnostic().WithLocation(0).WithArguments("Param2"), + }; + + await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + [WorkItem(3555, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3555")] + public async Task TestViolationOnRenamedExplicitlyImplementedInterfaceParameterNameAsync() + { + var testCode = @" +public interface ITest +{ + void Method(int param1, int {|#0:Param2|}); +} + +public class Test : ITest +{ + public void Method(int param1, int {|#1:Other|}) + { + } +}"; + + var expected = new[] + { + Diagnostic().WithLocation(0).WithArguments("Param2"), + Diagnostic().WithLocation(1).WithArguments("Other"), + }; + + await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestNoViolationOnAbstractParameterNameAsync() { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1313ParameterNamesMustBeginWithLowerCaseLetter.cs b/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1313ParameterNamesMustBeginWithLowerCaseLetter.cs index 348c6f2c9..869d5a2ae 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1313ParameterNamesMustBeginWithLowerCaseLetter.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1313ParameterNamesMustBeginWithLowerCaseLetter.cs @@ -137,12 +137,23 @@ private static bool NameMatchesAbstraction(ParameterSyntax syntax, SemanticModel if (methodSymbol.IsOverride) { - // OverridenMethod can be null in case of an invalid method declaration -> exit because there is no meaningful analysis to be done. + // OverriddenMethod can be null in case of an invalid method declaration -> exit because there is no meaningful analysis to be done. if ((methodSymbol.OverriddenMethod == null) || (methodSymbol.OverriddenMethod.Parameters[index].Name == syntax.Identifier.ValueText)) { return true; } } + else if (methodSymbol.ExplicitInterfaceImplementations.Length > 0) + { + // Checking explicitly implemented interface members here because the code below will not handle them correctly + foreach (var interfaceMethod in methodSymbol.ExplicitInterfaceImplementations) + { + if (interfaceMethod.Parameters[index].Name == syntax.Identifier.ValueText) + { + return true; + } + } + } else { var containingType = methodSymbol.ContainingType;