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

1

12

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.

Dearth answered 24/1, 2021 at 18:52 Comment(3)
On github.com/dotnet/roslyn/blob/master/docs/features/… I read: "For code-based issues, the generator author should also consider implementing a diagnostic analyzer that identifies the problem, and offers a code-fix to resolve it."Sarre
I am having the same issue. Did you ever find a solution and/or explanation for the missing squiggly?Zap
@Zap Unfortunately, I have not found a good solution, though it should be possible to utilize a diagnostic analyzer as a workaround (as Kris Vandermotton stated). Regarding an explanation, I would imagine that Visual Studio simply isn't programmed to report source generator diagnostics until compilation occurs. Perhaps it is a feature that Microsoft can add in the future.Dearth
P
6

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.

Pants answered 22/11, 2021 at 7:57 Comment(2)
Thanks for your attempt. It seems that I should write the known error diagnostics in the analyzer and keep the source generator reporting the unknown error because the latter one cannot draw red underlines although they are in the same assembly.Plumbaginaceous
This seems to have now been fixed in the most recent version of Visual Studio, with the unfortunate consequence that I have diagnostics appearing twice.Pants

© 2022 - 2025 — McMap. All rights reserved.