Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make diagnostic errors reported by a C# source generator appear in the Visual Studio editor

I am attempting to write a C# source generator that throws a warning/error under certain conditions using GeneratorExecutionContext.ReportDiagnostic. My source generator is able to run and output errors successfully upon building a sample project in Visual Studio. However, my errors do not show up as green/red squiggles in the Visual Studio editor. This is supposed to be possible with Roslyn analyzers, according to Microsoft's documentation, but nothing is said of source generators specifically. Since source generators are treated like Roslyn analyzers, though, I imagine this should be possible. I've managed to replicate my issue with a small example, consisting of a source generator project and a test project on which to run the generator. As a test, the generator reports a diagnostic error whenever it sees a method that doesn't return void. I intend for red squiggles to appear under the offending method's name:

Source generator:

[Generator]
public class SampleGenerator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        DataReceiver r = (DataReceiver)context.SyntaxReceiver;
        foreach(MethodDeclarationSyntax method in r.Methods)
        {
            IMethodSymbol symbol = (IMethodSymbol)context.Compilation.GetSemanticModel(method.SyntaxTree).GetDeclaredSymbol(method);
            if(symbol.ReturnType.SpecialType != SpecialType.System_Void)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                new DiagnosticDescriptor(
                    "SG0001",
                    "Non-void method return type",
                    "Method {0} returns {1}. All methods must return void.",
                    "yeet",
                    DiagnosticSeverity.Error,
                    true), symbol.Locations.FirstOrDefault(), symbol.Name, symbol.ReturnType.Name));
            }
        }
        context.AddSource("yert", "namespace test { public class testclass { } }");
    }

    public void Initialize(GeneratorInitializationContext context)
    {
        context.RegisterForSyntaxNotifications(() => new DataReceiver());
    }
}

public class DataReceiver : ISyntaxReceiver
{
    public List<MethodDeclarationSyntax> Methods { get; } = new List<MethodDeclarationSyntax>();

    public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
    {
        if(syntaxNode is MethodDeclarationSyntax synt)
        {
            Methods.Add(synt);
        }
    }
}

Example code:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }

    static string ok() => "hello";
}

When I compile the example code with the generator, Visual Studio tells me that the build has errors, and correctly reports the custom diagnostic in the error list. I can click on the custom error, and my cursor moves to the offending method in the editor. However, no red squiggles appear. I know that my source generator is being run by Intellisense, because I am able to see the custom test namespace and class my generator defines.

Does Visual Studio support code underlining for diagnostics reported by C# source generators? If so, what is wrong with the above code? Thanks in advance.

like image 332
Douglas Dwyer Avatar asked Nov 06 '22 03:11

Douglas Dwyer


1 Answers

I solved this by separating out the code analysis logic into its own class and adding an analyzer and source generator into the same assembly, with the analysis logic only doing code emmission in the source generator. The analysis logic runs in different contexts, each context having a different reportdiagnostic, so it accepted an Action to report diagnostic.

like image 117
Frank Avatar answered Nov 12 '22 16:11

Frank