如何利用C# Roslyn編譯器寫一個簡單的代碼提示/錯誤檢查?

  • 2019 年 10 月 31 日
  • 筆記

OK, 廢話不多說,這些天在寫C#代碼時突然對於IDE提示有了一些想法,之前也有了解過,不過並沒有深入。

先看個截圖:

 

 

 一段再簡單不過的代碼了,大家注意看到 count 字段下面的綠色波浪線了嗎,我們通常為理解一個 warning ,鼠標移上去:

 

 

 提示“聲明了該字段但沒有使用過” 當然,這對項目代碼編譯沒有什麼影響。不過,我想了一下,如果我們可以重寫IDE的編譯器,把我們的一些規則寫進去,對於團隊

的代碼review其實是很高效的一件事情。我們通常的代碼review會有滯後,都是通過提交PR或代碼評審,如果我們把這個檢查在開發人員寫代碼的時候第一時間提示出來或給error提示,實現所見即所得,應該是一件很值得做的事情吧。

言歸正傳,我們要實現這一目的,“Roslyn” 就出場了,可以理解為 .NET Compiler Platform,一個.NET編譯平台。以前我們看“Roslyn” 是這樣的:

 

 

 源碼 -> 編譯-> 程序集, 然而這裡的編譯其實是不透明的,也稱“黑盒狀態”。但微軟開源之後,我們了解裏面其實有這些細節:

 

 

 

API包括Syntax、Symbol等 ,今天不細講這些內容,後面再寫分析器的時候我會給大家羅列出來用法。

下面我們看如何準備環境(安裝Roslyn):

1. 安裝VS要勾選.NET Compiler Platform

 

 

 2.VS2019 16.3以上版本 .NET Framework4.8 (老版本的vs似乎也可以 我沒有嘗試過)

3. 打開VS,新建項目-》 選擇Analyzer with Code Fix 模板,如下圖:

 

 

 

4. 項目創建後,可以看到右邊Solution窗口有三個項目:

 

 

 正常情況下默認啟動項目為 Analyzer1.Vsix (VS擴展插件 不了解的同學可以去學習一下vs自定義插件)

5. 我們直接暴力一點,F5運行調試,項目運行後,會重新啟動一個新的VS實例:

 

 

 

 

 細心的同學可以看到,此時我的窗口是啟動了倆個VS, 一個可以理解為“母體”,一個則是母體Copy出來的一份(這樣形容應該好理解)

6. 在創建出來的VS實例窗口,我們還是按照之前的做法,新建一個控制台應用程序:

 

 

可以看到實例VS創建出來的控制台應用程序,類名 Program有提示,意思是不能小寫,然後旁邊有個黃色的燈泡,大概可以猜出來點擊黃色燈泡可以解決

當前提示的問題,應該就是轉換為大寫。那麼,這個簡單的檢查代碼是如何寫出來的呢?

7. 調試“母體”,在母體VS 類名為Analyzer1Analyzer 的靜態方法AnalyzeSymbol打斷點:

 

 

打完斷點後,我在實例的VS窗口刪除了類Program 的最後一個字母m,母體斷點被觸發,這段代碼可以看到就是一個簡單的檢查判斷,最後創建一個Rule

報給給前端的編輯器。基本上後續重寫編譯平台都是使用Diagnostic.Create方法,不同的則是你要寫特定的邏輯來檢查你團隊的代碼。

當然,這裡分為倆個部分,一個是診斷(IDE提示,如綠色波浪線),一個是解決(黃色小燈泡里實現解決代碼)

 

今天大概就是這樣一個簡單的Demo,其實裏面挺複雜,後續會給大家主角講一下AnalyzeSymbol類里的一些模型以及主要API.

PS:Roslyn源碼已經在github上公開,感興趣的可以看看源碼,地址:https://github.com/dotnet/roslyn 裏面代碼還是很有價值的。

另外,提供一個Roslyn學習地址:https://github.com/ironcev/awesome-roslyn