dotnet / roslyn-sdk

Roslyn-SDK templates and Syntax Visualizer
MIT License
517 stars 256 forks source link

Source generators, how to debug? #526

Open b-straub opened 4 years ago

b-straub commented 4 years ago

How can a "Source generator" be debugged?

b-straub commented 4 years ago

Found the answers to one of my questions:

When invoked by CSharpGeneratorDriver e.g. during Unit testing, the generator code can be debugged.

danielcrenna commented 4 years ago

@b-straub How are you properly creating a testable SourceGeneratorContext?

b-straub commented 4 years ago

@danielcrenna

Please see my test repository for an example BlazorSourceGeneratorTests

aalmada commented 4 years ago

I'm porting my project from using Uno.SourceGeneration to the new source generators. Uno outputs the generated files exactly as proposed for source generators and I'm missing it.

danielcrenna commented 4 years ago

The response from Directory.GetCurrentDirectory() returns the consuming project folder, so it’s easy to emit a string builder to both Roslyn and a text file. I do this to spot check output.

On Mon, May 18, 2020 at 4:58 PM Antão Almada notifications@github.com wrote:

I'm porting my project from using Uno.SourceGeneration https://github.com/unoplatform/Uno.SourceGeneration to new source generators. Uno outputs the generated files exactly as proposed for source generators https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md#output-files and I'm missing it.

aalmada commented 4 years ago

@danielcrenna I added the following to the beginning of my Execute():

        // create a folder to serialize the generated source for debugging
        string? generatedPath = null;
#if DEBUG
        // place it inside obj so that source is not added to the project
        generatedPath = Path.Combine("obj", "Debug", "Generated");
        // delete source generated by previous build
        if (Directory.Exists(generatedPath))
                Directory.Delete(generatedPath, true);
        Directory.CreateDirectory(generatedPath);
#endif

and, for each generated file:

        var hitName = $"{containerClass.OriginalDefinition.MetadataName}.{extendedType.OriginalDefinition.MetadataName}.cs";
        var source = builder.ToString();
#if DEBUG
        File.WriteAllText(Path.Combine(generatedPath, hitName), source);
#endif
        context.AddSource(hitName, SourceText.From(source, Encoding.UTF8));

Still, it would be nice to have an official solution.

danielcrenna commented 4 years ago

@aalmada Oh, that is a much nicer way than I'm doing it, thanks for sharing.

pakrym commented 3 years ago

Take a look at this target: https://github.com/pakrym/jab/blob/main/src/Jab.Tests/Jab.Tests.csproj#L33

It generates the https://github.com/pakrym/jab/blob/main/src/Jab/Properties/launchSettings.json file that mimicks the csc invocation and allows for F5 debugging.

opekope2 commented 3 years ago

I debug my source generators by attaching vscode to the build process Add this code to the source generator:

using System;
using System.Diagnostics;
using System.Threading;

Console.Error.WriteLine($"PID: {Process.GetCurrentProcess().Id}");
while (!Debugger.IsAttached)
{
    Thread.Sleep(100);
}