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

本文关键字:适用于 文件 操作 节点 我的 何使 代码 诊断 语法 | 更新日期: 2023-09-27 18:33:39

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

有很多选择,但我很难让其中任何一个始终如一地工作。我已经设法实现了一个基本的语法节点操作,即注册到

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 中"处理?这也许只是罗斯林的一点整合,还没有完全完成吗?

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

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

对于已关闭的文件问题,我们打算从打开或关闭的文件报告所有诊断。 在预览中的"工具''选项''文本编辑器''C#''高级"中有一个用户选项,您可以切换该选项以在关闭的文件中包含诊断信息。 我们希望在VS 2015发布之前将其设为默认值。 但是,请注意,该选项仅适用于 VS 中的分析。 如果将分析器传递给编译器(通过在解决方案资源管理器中添加分析器,或使用分析器将 NuGet 包引用添加到包,而不是将 VSIX 安装到 Visual Studio 中(,则编译器将在用户生成时报告所有诊断,无论文件是否打开。

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

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

希望这有帮助!