From a4aa1814e2c20cfeb79a6483226d7bfc27b7c824 Mon Sep 17 00:00:00 2001 From: "mateusz.krzaczek" Date: Sat, 7 Mar 2026 14:13:43 +0100 Subject: [PATCH 1/3] Added SimpleMethodWithParameterTest --- .../SimpleMethodWithParameter.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 EasySourceGenerators.Tests/SimpleMethodWithParameter.cs diff --git a/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs b/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs new file mode 100644 index 0000000..526bfc6 --- /dev/null +++ b/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs @@ -0,0 +1,46 @@ +using EasySourceGenerators.Abstractions; + +namespace EasySourceGenerators.Tests; + +public class SimpleMethodWithParameterTests +{ + [Test] + public void ColorsClassLikeGenerator_ProducesExpectedRuntimeOutput() + { + SimpleMethodWithParameterClass testColorsClass = new SimpleMethodWithParameterClass(); + + int result = testColorsClass.SimpleMethodWithParameter(123123); + + Assert.That(result, Is.EqualTo(5)); + } + + [Test] + public void ColorsClassLikeGenerator_ProducesExpectedGeneratedCode() + { + string generatedCode = GeneratedCodeTestHelper.ReadGeneratedCode("SimpleMethodWithParameterClass_SimpleMethodWithParameter.g.cs"); + string expectedCode = """ + namespace EasySourceGenerators.Tests; + + partial class SimpleMethodWithParameterClass + { + public partial string SimpleMethodWithParameter() + { + return 5; + } + } + """.ReplaceLineEndings("\n").TrimEnd(); + + Assert.That(generatedCode, Is.EqualTo(expectedCode)); + } +} + +public partial class SimpleMethodWithParameterClass +{ + public partial int SimpleMethodWithParameter(int someIntParameter); + + [GeneratesMethod(sameClassMethodName: nameof(SimpleMethodWithParameter))] + private static int SimpleMethodWithParameter_Generator(int someIntParameter) + { + return 5; + } +} \ No newline at end of file From 4dc9cc3257d3524bc5c99f4f32b6beaa158dc1de Mon Sep 17 00:00:00 2001 From: "mateusz.krzaczek" Date: Sat, 7 Mar 2026 14:30:16 +0100 Subject: [PATCH 2/3] WIP --- .../SimpleMethodWithParameter.cs | 27 +++++++++++ .../AnalyzerReleases.Unshipped.md | 3 +- .../GeneratesMethodGenerator.Diagnostics.cs | 8 ++++ .../SimpleMethodWithParameter.cs | 46 ------------------- 4 files changed, 37 insertions(+), 47 deletions(-) create mode 100644 EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs delete mode 100644 EasySourceGenerators.Tests/SimpleMethodWithParameter.cs diff --git a/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs b/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs new file mode 100644 index 0000000..025e921 --- /dev/null +++ b/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs @@ -0,0 +1,27 @@ +namespace EasySourceGenerators.GeneratorTests; + +public class SimpleMethodWithParameterTests +{ + [Test] + public void SimpleMethodWithParameterTests_Test() + { + string source = """ + using EasySourceGenerators.Abstractions; + + namespace TestNamespace; + + public partial class SimpleMethodWithParameterClass + { + public partial int SimpleMethodWithParameter(int someIntParameter); + + [GeneratesMethod(sameClassMethodName: nameof(SimpleMethodWithParameter))] + private static int SimpleMethodWithParameter_Generator(int someIntParameter) + { + return 5; + } + } + """; + + //TODO: This should not compile and throw error MSGH007 + } +} \ No newline at end of file diff --git a/EasySourceGenerators.Generators/AnalyzerReleases.Unshipped.md b/EasySourceGenerators.Generators/AnalyzerReleases.Unshipped.md index 0db95df..8043d84 100644 --- a/EasySourceGenerators.Generators/AnalyzerReleases.Unshipped.md +++ b/EasySourceGenerators.Generators/AnalyzerReleases.Unshipped.md @@ -7,4 +7,5 @@ MSGH002 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator MSGH003 | GeneratesMethodGenerator | Disabled | GeneratesMethodGenerator MSGH004 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator MSGH005 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator -MSGH006 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator \ No newline at end of file +MSGH006 | GeneratesMethodGenerator | Error | GeneratesMethodGenerator +MSGH007 | GeneratesMethodGenerator | Error | GeneratesMethodGeneratorDiagnostics \ No newline at end of file diff --git a/EasySourceGenerators.Generators/GeneratesMethodGenerator.Diagnostics.cs b/EasySourceGenerators.Generators/GeneratesMethodGenerator.Diagnostics.cs index b24f756..d9a5dbf 100644 --- a/EasySourceGenerators.Generators/GeneratesMethodGenerator.Diagnostics.cs +++ b/EasySourceGenerators.Generators/GeneratesMethodGenerator.Diagnostics.cs @@ -53,4 +53,12 @@ internal static class GeneratesMethodGeneratorDiagnostics category: Category, defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); + + internal static readonly DiagnosticDescriptor CannotUseRuntimeParameterForCompileTimeGeneratorError = new( + id: "MSGH007", + title: "Cannot use runtime parameter for compile-time generator", + messageFormat: "Method generators cannot have any parameters, as they will be run at compile time to generate the method output value. Use MethodTemplate if you want to emit method body instead of single value.", + category: Category, + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); } diff --git a/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs b/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs deleted file mode 100644 index 526bfc6..0000000 --- a/EasySourceGenerators.Tests/SimpleMethodWithParameter.cs +++ /dev/null @@ -1,46 +0,0 @@ -using EasySourceGenerators.Abstractions; - -namespace EasySourceGenerators.Tests; - -public class SimpleMethodWithParameterTests -{ - [Test] - public void ColorsClassLikeGenerator_ProducesExpectedRuntimeOutput() - { - SimpleMethodWithParameterClass testColorsClass = new SimpleMethodWithParameterClass(); - - int result = testColorsClass.SimpleMethodWithParameter(123123); - - Assert.That(result, Is.EqualTo(5)); - } - - [Test] - public void ColorsClassLikeGenerator_ProducesExpectedGeneratedCode() - { - string generatedCode = GeneratedCodeTestHelper.ReadGeneratedCode("SimpleMethodWithParameterClass_SimpleMethodWithParameter.g.cs"); - string expectedCode = """ - namespace EasySourceGenerators.Tests; - - partial class SimpleMethodWithParameterClass - { - public partial string SimpleMethodWithParameter() - { - return 5; - } - } - """.ReplaceLineEndings("\n").TrimEnd(); - - Assert.That(generatedCode, Is.EqualTo(expectedCode)); - } -} - -public partial class SimpleMethodWithParameterClass -{ - public partial int SimpleMethodWithParameter(int someIntParameter); - - [GeneratesMethod(sameClassMethodName: nameof(SimpleMethodWithParameter))] - private static int SimpleMethodWithParameter_Generator(int someIntParameter) - { - return 5; - } -} \ No newline at end of file From 980470c2346c61b33a808978f79cb9446b35a80f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:07:46 +0100 Subject: [PATCH 3/3] Enforce MSGH007 for simple generators with parameters and finish SimpleMethodWithParameter test (#82) * Initial plan * Add MSGH007 validation for simple generators with parameters 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> --- .../SimpleMethodWithParameter.cs | 20 ++++++++++++++--- .../GeneratesMethodGenerationPipeline.cs | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs b/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs index 025e921..190889c 100644 --- a/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs +++ b/EasySourceGenerators.GeneratorTests/SimpleMethodWithParameter.cs @@ -1,4 +1,8 @@ -namespace EasySourceGenerators.GeneratorTests; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; + +namespace EasySourceGenerators.GeneratorTests; public class SimpleMethodWithParameterTests { @@ -22,6 +26,16 @@ private static int SimpleMethodWithParameter_Generator(int someIntParameter) } """; - //TODO: This should not compile and throw error MSGH007 + ImmutableArray diagnostics = GeneratorTestHelper.GetGeneratorOnlyDiagnostics(source); + + Diagnostic? msgh007 = diagnostics.FirstOrDefault(diagnostic => diagnostic.Id == "MSGH007"); + Assert.That(msgh007, Is.Not.Null, "Expected MSGH007 for simple generator method with runtime parameter."); + Assert.That(msgh007!.Location.IsInSource, Is.True, "MSGH007 should point to generator source."); + + TextSpan span = msgh007.Location.SourceSpan; + string highlightedCode = source.Substring(span.Start, span.Length); + Assert.That(highlightedCode, Does.Contain("SimpleMethodWithParameter_Generator(int someIntParameter)")); + Assert.That(highlightedCode, Does.Not.Contain("return 5;"), + "MSGH007 should highlight the generator method signature, not the method body."); } -} \ No newline at end of file +} diff --git a/EasySourceGenerators.Generators/GeneratesMethodGenerationPipeline.cs b/EasySourceGenerators.Generators/GeneratesMethodGenerationPipeline.cs index a52ab9d..22c8858 100644 --- a/EasySourceGenerators.Generators/GeneratesMethodGenerationPipeline.cs +++ b/EasySourceGenerators.Generators/GeneratesMethodGenerationPipeline.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; using System.Collections.Immutable; using static EasySourceGenerators.Generators.Consts; @@ -71,6 +72,21 @@ private static string GenerateSourceForGroup( compilation); } + List methodsWithParameters = methods + .Where(method => method.Symbol.Parameters.Length > 0) + .ToList(); + if (methodsWithParameters.Count > 0) + { + foreach (GeneratesMethodGenerationTarget methodWithParameters in methodsWithParameters) + { + context.ReportDiagnostic(Diagnostic.Create( + GeneratesMethodGeneratorDiagnostics.CannotUseRuntimeParameterForCompileTimeGeneratorError, + GetMethodSignatureLocation(methodWithParameters.Syntax))); + } + + return string.Empty; + } + return GenerateFromSimplePattern(context, firstMethod, compilation); } @@ -105,4 +121,10 @@ private static bool HasAttribute(IMethodSymbol methodSymbol, string fullAttribut return methodSymbol.GetAttributes() .Any(attribute => attribute.AttributeClass?.ToDisplayString() == fullAttributeTypeName); } + + private static Location GetMethodSignatureLocation(MethodDeclarationSyntax methodSyntax) + { + TextSpan signatureSpan = TextSpan.FromBounds(methodSyntax.SpanStart, methodSyntax.ParameterList.Span.End); + return Location.Create(methodSyntax.SyntaxTree, signatureSpan); + } }