我正在使用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集成的一部分,还没有完成?
(如果有用的话,我可以包括该类的完整代码-在这种情况下,我怀疑它比信号要多的噪音。)
RegisterCompilationEndAction
所了解的,确实是您所需要的,并且不一致触发的事实是一个错误。我会给发言人发电子邮件并询问。