Question: how could I compile code with source generator #67801
-
For example, I want to compile the code like below Console.WriteLine($"Hello is {RegexHelper.IsLowercase("Hello")}");
public partial class RegexHelper
{
// The Source Generator generates the code of the method at compile time
[System.Text.RegularExpressions.GeneratedRegex("^[a-z]+$")]
public static partial Regex LowercaseLettersRegex();
public static bool IsLowercase(string value)
{
return LowercaseLettersRegex().IsMatch(value);
}
} When I try to compile the code, I got an error as follows(I had referenced the analyzer dlls, may in a wrong way):
The code I used to compile the code: https://github.com/WeihanLi/SamplesInPractice/blob/ac8507c68390a6e7cc3daf1a5df35ee6b852ef86/RoslynSample/SourceGeneratorSample.cs Are there some examples on how to compile with the |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Works with .NET 7.0, fails with .NET 6.0, as the The error that comes with .NET 6.0 regarding the access modifier is because that attribute is missing in .NET 6.0. |
Beta Was this translation helpful? Give feedback.
-
@thomasclaudiushuber yeah, the regex source generator is introduced since .NET 7, it works for .NET 7 and above. There's the code I used to compile the code var code = @"
using System;
using System.Text.RegularExpressions;
Console.WriteLine($""Hello is {RegexHelper.IsLowercase(""Hello"")}"");
public partial class RegexHelper
{
[System.Text.RegularExpressions.GeneratedRegex(""^[a-z]+$"")]
public static partial Regex LowercaseLettersRegex();
public static bool IsLowercase(string value)
{
return LowercaseLettersRegex().IsMatch(value);
}
}";
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var assemblyName = $"MyApp.{Guid.NewGuid()}";
// Add a reference to the System.Text.RegularExpressions assembly
var references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).Assembly.Location),
MetadataReference.CreateFromFile(typeof(System.Text.RegularExpressions.Regex).Assembly.Location),
};
// reference analyzer dll contains the source generator, harded for local testing purpose only
var generatorProjectPath = @"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.0-preview.3.23174.8\analyzers\dotnet\cs\System.Text.Json.SourceGeneration.dll";
var projectReference = MetadataReference.CreateFromFile(generatorProjectPath);
var compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references.Append(projectReference),
options: new CSharpCompilationOptions(OutputKind.ConsoleApplication));
using var ms = new MemoryStream();
var result = compilation.Emit(ms);
if (result.Success)
{
ms.Seek(0, System.IO.SeekOrigin.Begin);
var assembly = Assembly.Load(ms.ToArray());
assembly.EntryPoint?.Invoke(null, Array.Empty<object>());
}
else
{
Console.WriteLine($"Compilation errors:");
foreach (var diagnostic in result.Diagnostics)
{
Console.WriteLine(diagnostic.ToString());
}
} |
Beta Was this translation helpful? Give feedback.
-
I don't see you using generators anywhere there? You'll need to use GeneratorDriver to actually run generators. |
Beta Was this translation helpful? Give feedback.
-
Hi @WeihanLi , OK, got it. I looked at your project. You're creating the raw compilation object. On that one, the source generator did not run. That's the reason why you're getting the error. You need to kick it off with a GeneratorDriver like I do here in this file: https://github.com/thomasclaudiushuber/mvvmgen/blob/main/src/MvvmGen.SourceGenerators.Tests/ViewModelGeneratorTests/Base/ViewModelGeneratorTestBase.cs Then you'll get another Compilation object that includes the generated sources. It works like this for your project:
You can close this issue, as it's not a .NET runtime issue. I've sent you a PR with the working code in your repo: WeihanLi/SamplesInPractice#1 Thank you for raising this issue, I'm sure it will help others when they read along here, |
Beta Was this translation helpful? Give feedback.
Hi @WeihanLi ,
OK, got it. I looked at your project. You're creating the raw compilation object. On that one, the source generator did not run. That's the reason why you're getting the error.
You need to kick it off with a GeneratorDriver like I do here in this file: https://github.com/thomasclaudiushuber/mvvmgen/blob/main/src/MvvmGen.SourceGenerators.Tests/ViewModelGeneratorTests/Base/ViewModelGeneratorTestBase.cs
Then you'll get another Compilation object that includes the generated sources.
It works like this for your project: