diff --git a/src/Analyzers/MSTest.Analyzers/DoNotUseShadowingAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DoNotUseShadowingAnalyzer.cs index 5fba21395b..abbefd8916 100644 --- a/src/Analyzers/MSTest.Analyzers/DoNotUseShadowingAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DoNotUseShadowingAnalyzer.cs @@ -112,7 +112,8 @@ private static bool IsMemberShadowing(ISymbol member, ISymbol baseMember) } // Compare methods - if (member is IMethodSymbol methodSymbol && baseMember is IMethodSymbol baseMethodSymbol) + if (member is IMethodSymbol methodSymbol && baseMember is IMethodSymbol baseMethodSymbol && methodSymbol.IsGenericMethod == baseMethodSymbol.IsGenericMethod + && !(methodSymbol.DeclaredAccessibility == Accessibility.Private && baseMethodSymbol.DeclaredAccessibility == Accessibility.Private)) { return methodSymbol.Name == baseMethodSymbol.Name && methodSymbol.Parameters.Length == baseMethodSymbol.Parameters.Length && diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index d14bf4f6cb..7855473260 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -375,7 +375,7 @@ internal static string DoNotUseShadowingDescription { } /// - /// Looks up a localized string similar to Member '{0}' is already exist in the base class. + /// Looks up a localized string similar to Member '{0}' already exists in the base class. /// internal static string DoNotUseShadowingMessageFormat { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index d7a17fdaf4..ff98060e2e 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -524,7 +524,7 @@ The type declaring these methods should also respect the following rules: Shadowing test members could cause testing issues (such as NRE). - Member '{0}' is already exist in the base class + Member '{0}' already exists in the base class Do not use shadowing diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 9f41e3a4be..91af9e06a1 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -287,8 +287,8 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - Member '{0}' is already exist in the base class - Člen {0} už v základní (kořenové) třídě existuje. + Member '{0}' already exists in the base class + Člen {0} už v základní (kořenové) třídě existuje. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 48b3e1d5df..202b00cd98 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -289,8 +289,8 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - Member '{0}' is already exist in the base class - Der Member "{0}" ist bereits in der Basisklasse vorhanden. + Member '{0}' already exists in the base class + Der Member "{0}" ist bereits in der Basisklasse vorhanden. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 5ee7dae34c..c5af60c9d1 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -287,8 +287,8 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - Member '{0}' is already exist in the base class - El miembro ''{0}'' ya existe en la clase base + Member '{0}' already exists in the base class + El miembro ''{0}'' ya existe en la clase base diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 9cd012044f..2ad341b45e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -287,8 +287,8 @@ Le type doit être une classe - Member '{0}' is already exist in the base class - Le membre '{0}' existe déjà dans la classe de base + Member '{0}' already exists in the base class + Le membre '{0}' existe déjà dans la classe de base diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index f3216dac89..dc5995df7b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -287,8 +287,8 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - Member '{0}' is already exist in the base class - Il membro '{0}' esiste già nella classe di base + Member '{0}' already exists in the base class + Il membro '{0}' esiste già nella classe di base diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 2a75233c01..d747f0efeb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -287,8 +287,8 @@ The type declaring these methods should also respect the following rules: - Member '{0}' is already exist in the base class - メンバー '{0}' は既に基本クラスに存在します + Member '{0}' already exists in the base class + メンバー '{0}' は既に基本クラスに存在します diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 6eea1458f9..37f0993abc 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -287,8 +287,8 @@ The type declaring these methods should also respect the following rules: - Member '{0}' is already exist in the base class - 멤버 '{0}'이(가) 기본 클래스에 이미 있습니다. + Member '{0}' already exists in the base class + 멤버 '{0}'이(가) 기본 클래스에 이미 있습니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 7d33d3c9d0..cb152e8552 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -287,8 +287,8 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - Member '{0}' is already exist in the base class - Element członkowski „{0}” już istnieje w klasie bazowej + Member '{0}' already exists in the base class + Element członkowski „{0}” już istnieje w klasie bazowej diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index a09bed1486..bc30b2c16a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -287,8 +287,8 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - Member '{0}' is already exist in the base class - O membro "{0}" já existe na classe base + Member '{0}' already exists in the base class + O membro "{0}" já existe na classe base diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 24fa92dc0a..0c5c99ba71 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -291,8 +291,8 @@ The type declaring these methods should also respect the following rules: - Member '{0}' is already exist in the base class - Элемент "{0}" уже существует в базовом классе + Member '{0}' already exists in the base class + Элемент "{0}" уже существует в базовом классе diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 6c74a3e32f..08688d9799 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -287,8 +287,8 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - Member '{0}' is already exist in the base class - Üye '{0}' zaten temel sınıfta var + Member '{0}' already exists in the base class + Üye '{0}' zaten temel sınıfta var diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index ab3a0e8c21..85fae7d2fd 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -287,8 +287,8 @@ The type declaring these methods should also respect the following rules: - Member '{0}' is already exist in the base class - 基类中已存在成员“{0}” + Member '{0}' already exists in the base class + 基类中已存在成员“{0}” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 89c0dc74ac..04320e91d8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -287,8 +287,8 @@ The type declaring these methods should also respect the following rules: - Member '{0}' is already exist in the base class - 成員 '{0}' 已存在於基類中 + Member '{0}' already exists in the base class + 成員 '{0}' 已存在於基類中 diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs index 71458475d9..9f3e51de07 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs @@ -48,6 +48,94 @@ public void Method() { } await VerifyCS.VerifyAnalyzerAsync(code); } + public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButBothArePrivate_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + public class BaseClass + { + private void Method() { } + } + + [TestClass] + public class DerivedClass : BaseClass + { + private void Method() { } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + + public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButBaseIsPrivate_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + public class BaseClass + { + private void Method() { } + } + + [TestClass] + public class DerivedClass : BaseClass + { + public void [|Method|]() { } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + + public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButDerivedClassIsPrivate_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + public class BaseClass + { + public void Method() { } + } + + [TestClass] + public class DerivedClass : BaseClass + { + private void [|Method|]() { } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + + public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButOneIsGeneric_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System; + [TestClass] + public class BaseTest + { + protected TObject CreateObject() + { + throw new NotImplementedException(); + } + } + + [TestClass] + public class ExtendedTest : BaseTest + { + private SomeType CreateObject() + { + throw new NotImplementedException(); + } + } + + public class SomeType + { + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_WithParameters_Diagnostic() { string code = """