From 847d22452d724334f403ddb18d2ead27f4e7db76 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 09:24:00 +0000 Subject: [PATCH 1/3] Initial plan From 03a2706e16871c6343870aa26006ac5eae4045e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 09:29:03 +0000 Subject: [PATCH 2/3] Fix MSTEST0057 to skip static constructors Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> --- ...houldPropagateSourceInformationAnalyzer.cs | 6 ++ ...PropagateSourceInformationAnalyzerTests.cs | 84 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs index 8b5b87b606..5e9d4acd70 100644 --- a/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs @@ -68,6 +68,12 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo foreach (IMethodSymbol constructor in namedTypeSymbol.Constructors) { + // Skip static constructors as they cannot have caller info parameters + if (constructor.IsStatic) + { + continue; + } + // Check if constructor has CallerFilePath and CallerLineNumber parameters bool hasCallerFilePath = false; bool hasCallerLineNumber = false; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodAttributeShouldPropagateSourceInformationAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodAttributeShouldPropagateSourceInformationAnalyzerTests.cs index 3584bca2f9..09b3a154e2 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodAttributeShouldPropagateSourceInformationAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodAttributeShouldPropagateSourceInformationAnalyzerTests.cs @@ -481,4 +481,88 @@ public DerivedTestMethodAttribute([CallerFilePath] string callerFilePath = "", [ await VerifyCS.VerifyCodeFixAsync(code, code); } + + [TestMethod] + public async Task WhenDerivedTestMethodAttributeWithStaticConstructor_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Runtime.CompilerServices; + + public class MyTestMethodAttribute : TestMethodAttribute + { + static MyTestMethodAttribute() + { + } + + public MyTestMethodAttribute([CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) + : base(callerFilePath, callerLineNumber) + { + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [TestMethod] + public async Task WhenDerivedTestMethodAttributeWithStaticField_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System; + using System.Runtime.CompilerServices; + + public class MyTestMethodAttribute : TestMethodAttribute + { + static DateTimeOffset s_field = new(); + + public MyTestMethodAttribute([CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) + : base(callerFilePath, callerLineNumber) + { + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [TestMethod] + public async Task WhenDerivedTestMethodAttributeWithStaticConstructorAndMissingCallerInfo_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + public class SomeTestMethodAttribute : TestMethodAttribute + { + static SomeTestMethodAttribute() + { + } + + public [|SomeTestMethodAttribute|]() + : base() + { + } + } + """; + + string fixedCode = """ + using System.Runtime.CompilerServices; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + public class SomeTestMethodAttribute : TestMethodAttribute + { + static SomeTestMethodAttribute() + { + } + + public SomeTestMethodAttribute([CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1) + : base(callerFilePath, callerLineNumber) + { + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } } From 3829c127b8d71cb031f598a95cf9f49dd0640666 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 12 Nov 2025 11:04:44 +0100 Subject: [PATCH 3/3] Only check instance constructors --- ...odAttributeShouldPropagateSourceInformationAnalyzer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs index 5e9d4acd70..75a850cd86 100644 --- a/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestMethodAttributeShouldPropagateSourceInformationAnalyzer.cs @@ -66,14 +66,8 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo return; } - foreach (IMethodSymbol constructor in namedTypeSymbol.Constructors) + foreach (IMethodSymbol constructor in namedTypeSymbol.InstanceConstructors) { - // Skip static constructors as they cannot have caller info parameters - if (constructor.IsStatic) - { - continue; - } - // Check if constructor has CallerFilePath and CallerLineNumber parameters bool hasCallerFilePath = false; bool hasCallerLineNumber = false;