我如何使我的代码诊断语法节点操作对关闭的文件起作用?

问题描述 投票:72回答:1

我正在使用Roslyn构建一组代码诊断程序(在VS2015 Preview中)。理想情况下,我希望它们产生的任何错误都可以作为持久错误,就像我违反了正常的语言规则一样。

有很多选择,但是我很难让它们中的任何一个始终如一地工作。我设法实现了基本的语法节点操作,即一个在

中注册的操作
context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);

在我的诊断类的Initialize方法中。瞧,当我打开一个违反此诊断的文件时(运行VSIX项目时),VS2015显示错误:

  • 在代码右下的红色花体
  • 空白处的红色块
  • 错误列表中的错误

但是,当我关闭文件时,错误消失了。

我也尝试过使用context.RegisterCompilationEndAction,但这有两个问题:

  • 似乎不一致地开火。 通常当我打开解决方案时,它会触发,但并非总是如此。它不会在清理/重建时启动,这似乎很奇怪。
  • 尽管诊断是在分析方法中触发的[[直接,但为了实施我正在使用访问者的诊断,像这样-可能无能为力:

    private static void AnalyzeEndCompilation(CompilationEndAnalysisContext context) { foreach (var tree in context.Compilation.SyntaxTrees) { var visitor = new ReportingVisitor(context.Compilation.GetSemanticModel(tree)); visitor.Visit(tree.GetRoot()); foreach (var diagnostic in visitor.Diagnostics) { context.ReportDiagnostic(diagnostic); } } }
    [我知道正在创建诊断程序-ReportDiagnostic行上的断点多次被击中-但我在错误列表中没有看到任何内容。 (与此同时,在方法开始处进行类似的ReportDiagnostic调用,或者在每个语法树中使用文件路径进行一次调用,显示为[[does
    。)

我在这里做错了什么?如果可行,第一种方法(语法节点操作)将是理想的-它恰好为我提供了所需的上下文。在项目属性中是否有一些设置,我需要使编译器将其用于“完整项目”编译,以及仅用于交互式“在IDE中”处理?这可能只是Roslyn集成的一部分,还没有完成?

((如果有用的话,我可以包括该类的完整代码-在这种情况下,我怀疑它比信号要多。)
c# visual-studio-2015 roslyn analyzer diagnostics
1个回答
45
投票
all] >在用户构建时进行诊断,无论文件是否打开。

关于RegisterCompilationEndedAnalyzer的第二个问题,在VS 2015预览版的Visual Studio中无法可靠地调用它。这是因为我们进行了一些优化,以避免重新分析所有方法体内的“局部”更改。由于类似的原因,我们当前不报告位置in

方法主体报告的错误。我们最近进行了更改,以使VS在较长的延迟后将开始全面的重新分析,因此在以后的构建中应可靠地调用RegisterCompilationEndedAnalyzer,并且无论位置在哪里,我们都会报告错误。

但是,对于您而言,正确的做法是使用SyntaxNodeAnalyzer,切换VS选项以在关闭的文件中启用诊断,并将诊断附加到项目编译选项。

希望这会有所帮助!
© www.soinside.com 2019 - 2024. All rights reserved.