0

我有一个 C# 源代码生成器,如果在生成过程中引发异常,我想报告一个警告。

我可以成功发出带有描述的警告,但是我找不到包含更多详细信息的方法,我在报告的其他警告中看到了这些详细信息。

这是我到目前为止所得到的:

[Generator]
public sealed partial class MyGenerator : ISourceGenerator
{
    private static readonly DiagnosticDescriptor UnexpectedErrorDiagnostic = new DiagnosticDescriptor(
        id: "MYCUSTOMID001",
        title: "Unexpected Error During Generation",
        messageFormat: "Error for object",
        category: "Design",
        DiagnosticSeverity.Warning, isEnabledByDefault: true);

    public void Execute(GeneratorExecutionContext context)
    {
        try
        {
            // Some logic, which might throw an exception
        }
        catch (Exception ex)
        {
            context.ReportDiagnostic(Diagnostic.Create(UnexpectedErrorDiagnostic, Location.None));
        }
    }
}

当这被提出时,代码和描述设置正确:

警告在 VS2022 错误列表中正确显示

我想做的是在同一个诊断中包含异常详细信息,以便可以扩展警告,就像我看到的其他一些警告一样:

扩展的 VS2022 错误列表中的警告显示更多详细信息

我尝试在 Diagnostic.Create 期间设置 Properties 属性,但它们没有显示在任何地方。

如何在自定义诊断中包含此更多信息?

4

1 回答 1

2

你所看到RS2000的有点不同。这是从诊断分析器报告的诊断规则。它使用相同的DiagnosticDescriptor类,但对源生成器的处理方式不同。例如,DiagnosticAnalyzer期望派生类提供支持的诊断列表(通过SupportedDiagnostics)。

诊断报告DiagnosticAnalyzer

这是一个诊断分析器的极简示例:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class MyDiagnosticAnalyzer : DiagnosticAnalyzer
{
    private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
        id: "MYCUSTOMID001",
        title: "Unexpected Error",
        messageFormat: "Error for object",
        category: "Design",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true,
        description: "MYCUSTOMID001 long description. This line will be shown in the error list panel");

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

    public override void Initialize(AnalysisContext context)
    {
        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
        context.EnableConcurrentExecution();
        context.RegisterSyntaxTreeAction(AnalyzeAction);
    }

    private static void AnalyzeAction(SyntaxTreeAnalysisContext context)
    {
        // ...
        context.ReportDiagnostic(Diagnostic.Create(Rule, Location.None));
    }
}

它报告一个警告,其中包含从实例的Descriptiongetter 中使用的可扩展详细信息:DiagnosticDescriptor

分析仪

诊断报告SourceGenerator

虽然它适用于诊断分析器,但它似乎不适用于源生成器。

[Generator]
public sealed class MySourceGenerator : ISourceGenerator
{
    public void Initialize(GeneratorInitializationContext context)
    {
    }

    public void Execute(GeneratorExecutionContext context)
    {
        // ...
        var descriptor = new DiagnosticDescriptor(
            id: "MYCUSTOMID002",
            title: "Unexpected Error",
            messageFormat: "Error for object",
            category: "Design",
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true,
            description: "MYCUSTOMID002 long description. This line will be shown in the error list panel");

        context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None));
    }
}

如我们所见,Description消息中没有显示:

发电机 1


解决方法(嗯,不是真的)

您仍然可以使用该MessageFormat属性从源生成器提供有意义的诊断详细信息,并将正确的格式参数传递给Diagnostic.Create以后。

这是一个例子:

public void Execute(GeneratorExecutionContext context)
{
    // ...
    var descriptor = new DiagnosticDescriptor(
        id: "MYCUSTOMID002",
        title: "Unexpected Error",
        messageFormat: "Error for object: {0}",
        category: "Design",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true);

    context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None, "Exception long description, stack trace, etc."));
}

它将产生以下消息:

生成器 2

但我知道这不是您正在寻找的。

于 2021-11-30T09:45:49.713 回答