c# - 在 Roslyn 中获取 ISymbol 信息的通用方法
问题描述
我正在编写一个文档生成器,它使用 Roslyn 从 C# 源代码中提取信息。作为其中的一部分,我需要获取ISymbol
各种类型的SyntaxNodes
. 但是,似乎没有一种通用的方法可以做到这一点。
假设我想确定某种类型节点的可访问性(例如private
,、、、protected
)public
。DeclaredAccessibility
如果节点包含该属性,则该信息很容易获得。但似乎没有指示给定节点的接口。因此,您必须使用反射来查看是否具有该属性,这可能在计算上很昂贵,或者确切地知道您正在处理的节点类型,以便您可以将其转换为正确的类型。
这是一个基于相关情况的示例,涉及确定 a 的可访问性const
:
public const string Dummy = "abc";
当我遍历语法树并使用相应的语义模型来提取可访问性信息时,我最终会这样做:
SyntaxNode nodeToTest = null;
switch( syntaxNode )
{
case FieldDeclarationSyntax fieldDecNode:
// all the fields expressed in a field declaration share the same
// modifiers (e.g., public, static, const) and type; they're basically
// all from the same statement/line of code
nodeToTest = fieldDecNode.Declaration.Variables.FirstOrDefault();
break;
default:
nodeToTest = syntaxNode;
break;
}
var nodeInfo = syntaxTree.Model.GetDeclaredSymbol( nodeToTest );
这行得通,如果这是最不坏的方法,我会接受它(并在遇到其他怪癖时扩展它)。但这感觉很笨拙,我想使用更好/更灵活的方法。
解决方案
你考虑过使用CSharpSyntaxWalker
吗?
表示一个 CSharpSyntaxVisitor,它下降整个 CSharpSyntaxNode 图,以深度优先的顺序访问每个 CSharpSyntaxNode 及其子 SyntaxNodes 和 SyntaxTokens。
您可以创建自己的 walker 类,该类继承自CSharpSyntaxWalker
该类并覆盖SyntaxNode
您关注的每个子类型的访问函数。这意味着节点的类型将在函数中已知。对于您的示例,您将覆盖该VisitFieldDeclaration
方法。SyntaxNode
文档链接显示了您可以覆盖的每种访问者类型的方法。
internal class TestWalker : CSharpSyntaxWalker
{
private readonly SemanticModel _model;
public TestWalker(SemanticModel model)
{
_model = model;
}
public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
{
// do your const field accessibility analysis here
}
// override any other syntax visitors here
}
您可以将所需的任何其他实现细节添加到该类中。当您需要进行分析时,实例化您的步行器并调用您想要开始步行的Visit()
方法。SyntaxNode
推荐阅读
- reactjs - 管理钩子内的多个状态
- java - 春季 Azure Pipeline Gradle 构建失败
- git - 无需直接连接即可同步两个 Git 存储库
- selenium - Selenium 服务器和 Chromedriver 在 Linux 上不起作用
- c# - 带有 InterpolateColors 的 LinearGradientBrush 无法正确渲染小位置值
- firebase - Firebase 托管重定向到子文件夹
- python - Pygame“定时事件”功能
- c# - Visual Studio 2017 中没有扩展菜单
- javascript - 如何更新对象数组中的对象字段?
- r - 有没有办法将饼图的标准颜色替换为图片?