如何使我的代码诊断语法节点操作对关闭的文件起作用? [英] How can I make my code diagnostic syntax node action work on closed files?

查看:46
本文介绍了如何使我的代码诊断语法节点操作对关闭的文件起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Roslyn(在 VS2015 预览版中)构建一组代码诊断.理想情况下,我希望他们产生的任何错误都表现为持续性错误,就好像我违反了正常的语言规则一样.

I'm building a set of code diagnostics using Roslyn (in VS2015 Preview). Ideally, I'd like any errors they produce to act as persistent errors, just as if I were violating a normal language rule.

有很多选择,但我很难让它们中的任何一个都能一致地工作.我设法实现了一个基本的语法节点操作,即一个注册

There are a bunch of options, but I'm having a hard time getting any of them to work consistently. I've managed to implement a rudimentary syntax node action, i.e. one registered with

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);

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

in the Initialize method of my diagnostic class. Lo and behold, when I open up a file which violates this diagnostic (while running the VSIX project), VS2015 shows an error:

  • 右侧代码下方的红色波浪线
  • 边距中的红色块
  • 错误列表中的错误

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

However, the error goes away when I close the file.

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

I've tried using context.RegisterCompilationEndAction as well, but this has two problems:

  • 它似乎不一致地触发.通常当我打开解决方案时,它会触发,但并非总是如此.它不会在清理/重建时触发,这看起来很奇怪.
  • 虽然诊断直接在分析方法中创建,但为了实现诊断,我正在使用访问者,就像这样 - 这可能是无能的:

  • It seems to fire inconsistently. Usually when I open the solution it fires, but not always. It doesn't fire on a clean/rebuild, which seems odd.
  • Although diagnostics created directly in the analysis method fire, in order to implement the diagnostics I'm using a visitor, like this - which may be inept:

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 调用,或每个带有文件路径的语法树调用一个,确实会显示出来.)

I know that the diagnostics are being created - a breakpoint on the ReportDiagnostic line is hit several times - but I'm not seeing anything in the error list. (Whereas a similar ReportDiagnostic call at the start of the method, or one per syntax tree with the file path, does get shown.)

我在这里做错了什么?如果可行,第一种方法(语法节点操作)将是理想的 - 它准确地为我提供了我需要的上下文.项目属性中是否有一些设置需要让编译器将其用于完整项目"编译以及IDE 中"处理的交互式处理?这可能只是尚未完成的 Roslyn 集成?

What am I doing wrong here? The first approach (a syntax node action) would be ideal if feasible - it gives me exactly the context I need. Is there some setting in the project properties that I need to make the compiler use that for "full project" compilation as well as just interactive "in the IDE" handling? Is this perhaps just a bit of Roslyn integration which isn't quite finished yet?

(如果有用,我可以包含该类的完整代码 - 在这种情况下,我怀疑它会比信号更多的噪音.)

(I can include the full code for the class if it would be useful - in this case I suspect it would be more noise than signal though.)

推荐答案

对于关闭的文件问题,我们的目的是报告所有诊断信息,无论是打开的还是关闭的文件.在 Tools\Options\Text Editor\C#\Advanced 的预览中有一个用户选项,您可以切换它以在关闭的文件中包含诊断.我们希望在 VS 2015 发布之前将其设为默认值.但是,请注意该选项仅适用于 VS 内的分析.如果你的分析器被传递给编译器(通过在解决方案资源管理器中添加一个分析器,或者将 NuGet 包引用添加到带有分析器的包,而不是在 Visual Studio 中安装 VSIX),那么编译器将报告all 用户构建时的诊断,无论文件是否打开.

For the closed file issues, it's our intent that all diagnostics will be reported, from either open or closed files. There is a user option for it in the preview at Tools\Options\Text Editor\C#\Advanced that you can toggle to include diagnostics in closed files. We hope to make this the default before VS 2015 is released. However, note that the option only applies to analysis within VS. If your analyzer is passed to the compiler (by adding an analyzer in Solution Explorer, or adding a NuGet package reference to a package with an analyzer, as opposed to installing a VSIX into Visual Studio), then the compiler will report all diagnostics when the user builds, regardless of whether the files are open or not.

对于 RegisterCompilationEndedAnalyzer 的第二个问题,它在 VS 2015 预览版中的 Visual Studio 中无法可靠地调用.这是因为我们做了一些优化,以避免重新分析方法体内本地"更改的所有内容.出于类似的原因,我们目前不报告与位置in 方法主体报告的错误.我们最近刚刚更改了这一点,以便 VS 将在更长的延迟后开始完整的重新分析,因此 RegisterCompilationEndedAnalyzer 应该在未来的构建中可靠地调用,并且无论位置如何,我们都会报告错误.

For the second issue with RegisterCompilationEndedAnalyzer, it isn't reliably called inside Visual Studio in the VS 2015 Preview. This is because we do some optimizations to avoid re-analyzing everything for "local" changes inside method bodies. For similar reasons, we currently don't report errors that are reported with locations in method bodies. We've just recently changed that so that VS will kick off a full re-analysis after a longer delay and so RegisterCompilationEndedAnalyzer should be called reliably in future builds, and we will report errors regardless of location.

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

However, for your case the correct thing to do is stay with a SyntaxNodeAnalyzer, switch the VS option to enable diagnostics in closed files, and attach your diagnostic to the project compilation options.

希望这会有所帮助!

这篇关于如何使我的代码诊断语法节点操作对关闭的文件起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆