我如何使我的代码诊断语法节点的行动工作在封闭的文件?

我正在使用Roslyn构build一组代码诊断(在VS2015 Preview中)。 理想情况下,我想要把他们产生的任何错误当作持续的错误,就像我违反了正常的语言规则一样。

有一堆select,但我很难让他们中的任何一个始终如一地工作。 我设法实现了一个基本的语法节点行动,即一个注册

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression); 

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

  • 在正确的位代码下红色的波浪曲线
  • 红色块在边缘
  • 错误列表中的错误

但是,closures文件时错误消失。

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

  • 这似乎是不一致的。 通常当我打开解决scheme时,它会触发,但并非总是如此。 它不会在干净/重build上开火,这看起来很奇怪。
  • 尽pipe在分析方法中直接创build了诊断,但为了实现诊断,我使用了一个访问者,就像这样 – 这可能是无用的:

     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); } } } 

    我知道正在创build诊断程序 – ReportDiagnostic行上的断点会被点击几次 – 但是在错误列表中没有看到任何内容。 (而在方法的开始部分,或者在文件path的每个语法树中调用一个类似的ReportDiagnostic显示出来。)

我在这里做错了什么? 第一种方法(语法节点操作)在可行的情况下是理想的 – 它给了我完全我需要的上下文。 在项目属性中是否有一些设置需要使编译器使用“完整项目”编译以及“在IDE中”交互处理? 这可能只是一个Roslyn集成,还没有完成呢?

(如果有用的话,我可以包含完整的代码 – 在这种情况下,我怀疑它会比信号更噪声)。

对于已closures的文件问题,我们的意图是,所有的诊断信息都会从打开或closures的文件中报告。 在Tools \ Options \ Text Editor \ C#\ Advanced的预览中有一个用户选项,您可以切换到在closures的文件中包含诊断。 我们希望在VS 2015发布之前将其作为默认设置。 但是请注意,该选项仅适用于VS内的分析。 如果您的分析器被传递给编译器(通过在解决scheme资源pipe理器中添加分析器,或者使用分析器将NuGet包引用添加到包中,而不是在Visual Studio中安装VSIX),那么编译器将会报告所有的诊断用户构build,而不pipe文件是否打开。

对于RegisterCompilationEndedAnalyzer的第二个问题,在VS 2015 Preview中,它不可靠地在Visual Studio中调用。 这是因为我们做了一些优化,以避免重新分析方法体内“局部”更改的所有内容。 由于类似的原因,我们目前不报告方法体中的位置报告的错误。 我们刚刚改变了这个,所以VS会在更长的延迟后开始全面的重新分析,所以RegisterCompilationEndedAnalyzer在未来版本中应该被可靠地调用,并且我们将报告错误,而不pipe位置如何。

但是,对于您的情况,正确的做法是使用SyntaxNodeAnalyzer,切换VS选项以在closures的文件中启用诊断,然后将诊断程序附加到项目编译选项。

希望这可以帮助!