Roslyn诊断分析器异常:节点位置超文件末尾,无错误红线
Roslyn诊断分析器位置错误,无法显示错误红线
我开发了首个Roslyn诊断分析器,通过NuGet安装到测试项目后,其余功能正常,但问题代码处无法显示错误红线。使用SyntaxNodeAnalysisContext.Node.GetLocation()获取位置并写入诊断信息后,错误窗口显示位置为SourceFile(C:\..\..\..\Program.cs[275..276)),但该Program.cs文件仅27行。我正在分析属性声明及其关联特性,相关代码如下:
private static void AnalyzeParameters(SyntaxNodeAnalysisContext context, IMethodSymbol methodSymbol) { var parameters = methodSymbol.Parameters; if (parameters.Length != 1) { context.ReportDiagnostic(Diagnostic.Create(DD_INVALID_PARAM_COUNT, context.Node.GetLocation(), methodSymbol.Name, parameters.Length)); return; } var propertyType = ((PropertyDeclarationSyntax)context.Node).Type.ToString(); var methodInputType = parameters.First().Type.ToString(); if (propertyType != methodInputType) { context.ReportDiagnostic(Diagnostic.Create(DD_INVALID_PARAM_TYPE, context.Node.GetLocation(), methodSymbol.Name, methodInputType, propertyType)); } }
问题原因
- 错误的位置来源:
context.Node.GetLocation()获取的位置可能并非测试项目中用户代码的节点位置,而是来自元数据(如关联特性所在的引用程序集)或非目标语法节点,导致行号指向不存在的位置。 - 未做类型校验:代码中直接强制转换
(PropertyDeclarationSyntax)context.Node,若传入的节点并非用户代码中的属性声明节点,会导致获取到错误的位置信息。
解决方案
添加类型校验,确保节点正确性
在方法开头先校验context.Node的类型,避免处理非预期节点:if (!(context.Node is PropertyDeclarationSyntax propertyNode)) { return; }定位到用户代码中的具体语法节点
不要使用整个属性节点的位置,而是选择需要标记的具体部分(如属性名称、类型),确保位置指向测试项目的实际代码行:- 标记属性名称:
propertyNode.Identifier.GetLocation() - 标记属性类型:
propertyNode.Type.GetLocation()
- 标记属性名称:
修改后的完整代码
private static void AnalyzeParameters(SyntaxNodeAnalysisContext context, IMethodSymbol methodSymbol) { if (!(context.Node is PropertyDeclarationSyntax propertyNode)) { return; } var parameters = methodSymbol.Parameters; if (parameters.Length != 1) { var diagnostic = Diagnostic.Create(DD_INVALID_PARAM_COUNT, propertyNode.Identifier.GetLocation(), methodSymbol.Name, parameters.Length); context.ReportDiagnostic(diagnostic); return; } var propertyType = propertyNode.Type.ToString(); var methodInputType = parameters.First().Type.ToString(); if (propertyType != methodInputType) { var diagnostic = Diagnostic.Create(DD_INVALID_PARAM_TYPE, propertyNode.Type.GetLocation(), methodSymbol.Name, methodInputType, propertyType); context.ReportDiagnostic(diagnostic); } }额外检查项
确认诊断规则的Descriptor定义中,LocationOptions设置正确(通常为LocationOptions.None),避免因配置错误导致位置解析异常。
内容的提问来源于stack exchange,提问作者Dominick
相关产品推荐
相关产品推荐

