如何定位包含指定SyntaxNode的MethodDeclarationSyntax?
直接从目标语法节点本身向上遍历祖先节点就可以了,不需要绕路通过Location找Token再处理。试试这段代码:
MethodDeclarationSyntax callingMethod = node .AncestorsAndSelf() .OfType<MethodDeclarationSyntax>() .FirstOrDefault();
为什么你之前的方法返回null?
你之前的代码是从节点的Location获取SourceSpan的起始Token,再通过这个Token的Parent去遍历祖先。这个路径很容易出错——比如Token的直接Parent可能不是你预期的语法节点层级,导致后续的祖先遍历找不到MethodDeclaration。
而直接调用node.AncestorsAndSelf()会从你已经持有的from1.Age对应的语法节点(应该是MemberAccessExpressionSyntax)开始,逐层向上遍历所有父节点,直到找到第一个MethodDeclarationSyntax,这是Roslyn API中查找包含节点的标准做法,可靠性高得多。
关于你提到的Parent为null的情况
你说node.Parent.Parent返回的BinaryExpression再调用Parent得到null,这大概率是描述上的小误差或者节点识别错误。结合你的源代码,from1.Age的语法树层级应该是这样的:MemberAccessExpressionSyntax (from1.Age) → BinaryExpressionSyntax (from1.Age + to1.Age) → BinaryExpressionSyntax ((from1.Age + to1.Age) * to1.Age) → ArgumentSyntax → ArgumentListSyntax → ElementAccessExpressionSyntax → EqualsValueClauseSyntax → LocalDeclarationStatementSyntax → BlockSyntax → MethodDeclarationSyntax
正常情况下,不会出现中间某个节点Parent为null的情况。如果确实遇到了,建议先通过node.ToString()确认你持有的节点是否正确,或者检查语法树是否完整加载(比如是否是从完整的源码文件解析而来,而非片段)。
内容的提问来源于stack exchange,提问作者Tamas Ionut

