首页 文章

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

提问于
浏览
69

我正在使用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 调用,或者每个语法树有一个带有文件路径的调用,但是会显示出来 . )

我在这做错了什么?如果可行的话,第一种方法(语法节点动作)将是理想的 - 它完全给出了我需要的上下文 . 项目属性中是否有一些设置需要使编译器使用“完整项目”编译以及“在IDE中处理”交互?这可能只是Roslyn集成的一点还没有完成吗?

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

1 回答

  • 43

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

    对于 RegisterCompilationEndedAnalyzer 的第二个问题,报告包含方法体中位置的错误并不是't reliably called inside Visual Studio in the VS 2015 Preview. This is because we do some optimizations to avoid re-analyzing everything for 1251352 changes inside method bodies. For similar reasons, we currently don' t . 我们刚刚改变了这一点,以便VS在更长的延迟后启动完整的重新分析,因此在未来的版本中应该可靠地调用 RegisterCompilationEndedAnalyzer ,我们将报告错误,无论位置如何 .

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

    希望这可以帮助!

相关问题