Skip to content

Commit 5781383

Browse files
Copilotdex3r
andauthored
Add MSGH006 diagnostic for SwitchCase argument type mismatch (#41)
* Initial plan * Add MSGH006 diagnostic for SwitchCase argument type mismatch Co-authored-by: dex3r <3155725+dex3r@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dex3r <3155725+dex3r@users.noreply.github.com>
1 parent 934acfa commit 5781383

4 files changed

Lines changed: 84 additions & 1 deletion

File tree

MattSourceGenHelpers.GeneratorTests/GeneratorDiagnosticsTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,62 @@ private static int GetValue_Generator(int key)
244244
"Error message should hint that a partial method was called during generation");
245245
}
246246

247+
// -----------------------------------------------------------------------
248+
// MSGH006 – SwitchCase argument type mismatch
249+
// -----------------------------------------------------------------------
250+
251+
[Test]
252+
public void GeneratesMethod_SwitchCaseWithWrongArgumentType_EmitsMSGH006()
253+
{
254+
string source = """
255+
using MattSourceGenHelpers.Abstractions;
256+
257+
namespace TestNamespace;
258+
259+
public static partial class MyClass
260+
{
261+
public static partial int GetValue(int key);
262+
263+
[GeneratesMethod(nameof(GetValue))]
264+
[SwitchCase(arg1: "aaa")]
265+
private static int GetValue_Generator(int key) => 42;
266+
}
267+
""";
268+
269+
ImmutableArray<Diagnostic> diagnostics = GeneratorTestHelper.GetGeneratorOnlyDiagnostics(source);
270+
271+
Diagnostic? msgh006 = diagnostics.FirstOrDefault(d => d.Id == "MSGH006");
272+
Assert.That(msgh006, Is.Not.Null, "Expected MSGH006 diagnostic for SwitchCase argument type mismatch");
273+
Assert.That(msgh006!.GetMessage(), Does.Contain("string"),
274+
"Error message should mention the provided type");
275+
Assert.That(msgh006.GetMessage(), Does.Contain("int"),
276+
"Error message should mention the expected parameter type");
277+
}
278+
279+
[Test]
280+
public void GeneratesMethod_SwitchCaseWithCorrectArgumentType_DoesNotEmitMSGH006()
281+
{
282+
string source = """
283+
using MattSourceGenHelpers.Abstractions;
284+
285+
namespace TestNamespace;
286+
287+
public static partial class MyClass
288+
{
289+
public static partial int GetValue(int key);
290+
291+
[GeneratesMethod(nameof(GetValue))]
292+
[SwitchCase(arg1: 1)]
293+
private static int GetValue_Generator(int key) => 42;
294+
}
295+
""";
296+
297+
ImmutableArray<Diagnostic> diagnostics = GeneratorTestHelper.GetGeneratorOnlyDiagnostics(source);
298+
299+
Assert.That(diagnostics.Any(d => d.Id == "MSGH006"), Is.False,
300+
"Should not emit MSGH006 when SwitchCase argument type matches the parameter type");
301+
}
302+
247303
// -----------------------------------------------------------------------
248304
// Type mismatch between generator return type and partial method return type
249305
// -----------------------------------------------------------------------

MattSourceGenHelpers.Generators/AnalyzerReleases.Unshipped.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ MSGH001 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator
66
MSGH002 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator
77
MSGH003 | GeneratesMethodGenerator | Disabled | GeneratesMethodGenerator
88
MSGH004 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator
9-
MSGH005 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator
9+
MSGH005 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator
10+
MSGH006 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator

MattSourceGenHelpers.Generators/GeneratesMethodGenerator.Diagnostics.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,12 @@ internal static class GeneratesMethodGeneratorDiagnostics
4545
category: Category,
4646
defaultSeverity: DiagnosticSeverity.Error,
4747
isEnabledByDefault: true);
48+
49+
internal static readonly DiagnosticDescriptor SwitchCaseArgumentTypeMismatchError = new(
50+
id: "MSGH006",
51+
title: "SwitchCase argument type mismatch",
52+
messageFormat: "SwitchCase argument type '{0}' does not match the method parameter type '{1}'",
53+
category: Category,
54+
defaultSeverity: DiagnosticSeverity.Error,
55+
isEnabledByDefault: true);
4856
}

MattSourceGenHelpers.Generators/GeneratesMethodPatternSourceBuilder.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ internal static string GenerateFromSwitchAttributes(
6969
continue;
7070
}
7171

72+
if (partialMethod.Parameters.Length > 0)
73+
{
74+
ITypeSymbol? switchArgType = switchCaseAttribute.ConstructorArguments[switchCaseArgIndex].Type;
75+
ITypeSymbol partialMethodParamType = partialMethod.Parameters[0].Type;
76+
77+
if (switchArgType != null && !SymbolEqualityComparer.Default.Equals(switchArgType, partialMethodParamType))
78+
{
79+
Location attributeLocation = switchCaseAttribute.ApplicationSyntaxReference?.GetSyntax()?.GetLocation()
80+
?? switchMethod.Syntax.GetLocation();
81+
context.ReportDiagnostic(Diagnostic.Create(
82+
GeneratesMethodGeneratorDiagnostics.SwitchCaseArgumentTypeMismatchError,
83+
attributeLocation,
84+
switchArgType.ToDisplayString(),
85+
partialMethodParamType.ToDisplayString()));
86+
continue;
87+
}
88+
}
89+
7290
(string? result, string? error) = GeneratesMethodExecutionRuntime.ExecuteGeneratorMethodWithArgs(
7391
switchMethod.Symbol,
7492
allPartials,

0 commit comments

Comments
 (0)