C#语法解析之Roslyn - nicebug/nicebug.github.io GitHub Wiki

What is Roslyn

Roslyn是微软开源的.net编译器。编译器支持C#和VB代码编译,并提供丰富的代码分析API。

How to install Roslyn

Visual Studio中安装,在Package Manager Console:Install-Package Microsoft.CodeAnalysis -Version 1.1.1

在非Visual Studio中,使用nuget命令行工具:

nuget install Microsoft.Net.Compilers   # Install C# and VB compilers
nuget install Microsoft.CodeAnalysis    # Install Language APIs and Services

以下以Visual Studio中为例。

How Roslyn work

Roslyn将C#源码解析为SyntaxTree,分为3部分:Syntax Nodes,Syntax Tokens和Trivia。以如下代码为例:

    class TestFindReference
    {

        public void test()
        {
           
        }
      
    }

Syntax Visualizer中可以显示Syntax Tree的节点信息

Syntax Tree

整个TestFindReference类对应ClassDeclaration,test method对应MethodDeclaration,ClassDeclaration上查看Syntax Graph,得到SyntaxTree的具体节点信息。 Syntax Graph

How to use

如何使用Roslyn分析C#源码,实现Visual Studio的Find Reference功能?可参考Roslyn Samples中的例子FAQ(7)(https://github.com/dotnet/roslyn/wiki/FAQ#how-do-i-go-from-a-solution-to-find-all-references-on-a-symbol/type)

const string pathToSolution = @"..\..\..\SampleToAnalyze\SampleToAnalyze.sln";
const string projectName = "SampleToAnalyze";

// start Roslyn workspace
MSBuildWorkspace workspace = MSBuildWorkspace.Create();

// open solution we want to analyze
Solution solutionToAnalyze =
    workspace.OpenSolutionAsync(pathToSolution).Result;

// get the project we want to analyze out
// of the solution
Project sampleProjectToAnalyze =
    solutionToAnalyze.Projects
                        .Where((proj) => proj.Name == projectName)
                        .FirstOrDefault();
// get the project's compilation
// compilation contains all the types of the 
// project and the projects referenced by 
// our project. 
Compilation sampleToAnalyzeCompilation =
sampleProjectToAnalyze.GetCompilationAsync().Result;  

INamedTypeSymbol classToAnalyze = compilation.GetTypeByMetadataName(fullClassName);
            IMethodSymbol methodSymbol = classToAnalyze.GetMembers(methodName).FirstOrDefault() as IMethodSymbol;
// 查找Findreference获取结果列表
var results = SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result.ToList();