工具与准备
使用的IDE是Visual Studio 2017,之前试过用VS2013,在下载依赖项的时候出现了一些问题,可能是版本太老。
新建一个C#控制台程序,在项目管理器那里选择NuGet,进入界面之后搜索第三方包Microsoft.CodeAnalysis.CSharp
并下载安装。
第一次尝试
首先来尝试获取一下某一份的类名。
先上代码:
1 | using System; |
首先我们把整份代码用System.IO.File.ReadAllText
读进来。然后需要把代码文本进行分析,读成一份语法树。
1 | SyntaxTree tree = CSharpSyntaxTree.ParseText(codeStr); |
得到语法树之后,我们就可以遍历它的成员了。一般来说成员只会有一个。
接下来遍历所有成员的节点,节点可能会有三个:
- using定义
- namespace定义
- class定义
三者都继承于基类MemberDeclarationSyntax
。
现在我们的目的是取到这份代码里面所有的类的类名。于是判断每个节点的类型,如果是ClassDeclarationSyntax
类型就进行强转。
强转之后得到的childNodeClass
,我们就可以通过
1 | string theClassName = childNodeClass.Identifier.Text; |
来得到对应的类名了。
好,本期到此结束(误,只是留个坑啦
解决获取不到document的问题
1 | Install-Package Microsoft.Build.Tasks.Core -Version 16.0.461 |
遍历语法树并输出所有方法和字段
1 | using Microsoft.CodeAnalysis; |
现在针对一些常用的模式进行分析。
1 | class A |
看一下上面代码中这句代码的结构
1 | b.a.value = 2; |
- ExpressionStatement
b.a.value = 2;
- SimpleAssignmentExpression
b.a.value = 2
- SimpleAssignmentExpression
b.a.value
- SimpleMemberAccessExpression
b.a
- IdentifierName
b
- DotToken
.
- IdentifierName
a
- IdentifierName
- DotToken
.
- IdentifierName
value
- SimpleMemberAccessExpression
- EqualsToken
=
- NumericLiteralExpression
2
- SimpleAssignmentExpression
- SemicolonToken
;
- SimpleAssignmentExpression
再看方法调用
1 | b.a.Func(); |
- ExpressionStatement
b.a.Func(a);
- InvocationExpression
b.a.Func(a)
- SimpleMemberAccessExpression
b.a.Func
- SimpleMemberAccessExpression
b.a
- IdentifierName
b
- DotToken
.
- IdentifierName
a
- IdentifierName
- DotToken ‘.’
- IdentifierName
Func
- SimpleMemberAccessExpression
- ArgumentList
(a)
- OpenParenToken
(
- Argument
a
- IdentifierName
a
- IdentifierName
- CloseParenToken
)
- OpenParenToken
- SimpleMemberAccessExpression
- SemicolonToken
;
- InvocationExpression
接下来看函数的定义