p3c 插件,是怎么檢查出你那屎山的代碼?

      網友投稿 1227 2025-03-31

      一、前言


      你會對你用到都技術,好奇嗎?

      雖然我們都被稱為碼農,也都是寫著代碼,但因為所處場景需求的不同,所以各類碼農也都做著不一樣都事情。

      有些人統一規范、有些人開發組件、有些人編寫業務、有些人倒騰驗證,但越是工作內容簡單如CRUD一樣的碼農,用到別人提供好的東西卻是越多。一會安裝個插件、一會引入個Jar包、一會調別人個接口,而自己的工作就像是裝配工,東拼拼西湊湊,就把產品需求寫完了。

      壞了,這么干可能幾年下來,也不會有什么技術上都突破。因為你對那些使用都技術不好奇,不想知道它們是怎么實現的。就像阿里的P3C插件,是怎么檢查代碼分析出來我寫的拉胯的呢?

      二、P3C 插件是什么

      P3C 是阿里開源代碼庫的插件工程名稱,它以阿里巴巴Java開發手冊為標準,用于監測代碼質量的 IDEA/Eclipse 插件。

      源碼:https://github.com/alibaba/p3c

      插件安裝完成后,就可以按照編程規約,靜態分析代碼中出現的代碼:命名風格、常量定義、集合處理、并發處理、OOP、控制語句、注釋、異常等各項潛在風險,同時會給出一些優化操作和實例。

      在遵守開發手冊標準并按照插件檢查都情況下,還是可以非常好的統一編碼標準和風格都,也能剔除掉一些潛在都風險。

      如果你是新手編程用戶或者想寫出標準都代碼,那么非常建議你按照這樣都插件來輔助自己做代碼開發。當然如果你所在的公司也有相應都標準手冊和插件,也可以按照后遵守它都約定的。

      三、P3C 插件源碼

      在最開始使用這類代碼檢查都插件的時候,就非常好奇它是怎么發現我的屎山代碼的,用了什么樣都技術原理呢,如果我能分析下是不是也可以把這樣都技術手段用到其他地方。

      在分析這樣一個代碼檢查插件前,先思考要從 IDEA 插件都源碼查起,看看它是什么個邏輯,之后分析具體是如何使用都。其實這與一些其他的框架性源碼學習都是類似的,拿到官網都文檔、GitHub 對應的源碼,按照步驟進行構建、部署、測試、調試、分析,進而找到核心原理。

      P3C 以 IDEA 插件開發為例,主要涉及到插件部分和規約部分,因為是把規約檢查的能力與插件技術結合,所以會涉及到一些 IDEA 開發的技術。另外 P3C 插件涉及到都技術語言不只是 Java 還有一部分 kotlin 它是一種在 Java 虛擬機上運行的靜態類型編程語言。

      插件源碼:https://github.com/alibaba/p3c/blob/master/idea-plugin

      規約源碼:https://github.com/alibaba/p3c/tree/master/p3c-pmd

      1. 插件配置 p3c.xml

      翻看源碼最重要是要找到入口,這個入口通常也是你在使用插件、程序、接口等時候,最直接進入都那部分。

      那么我們在使用 P3C 插件的時候,最明顯的就是 編碼規約掃描 通過源碼中找到這個關鍵字,看它都涉及了哪個類都配置。

      action 是 IDEA 插件中用于配置窗體事件入口都地方,以及把這個操作配置到哪個按鈕下和對應都快捷鍵。

      2. 編碼規約掃描( AliInspectionAction)

      class AliInspectionAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return val analysisUIOptions = ServiceManager.getService(project, AnalysisUIOptions::class.java)!! analysisUIOptions.GROUP_BY_SEVERITY = true val managerEx = InspectionManager.getInstance(project) as InspectionManagerEx val toolWrappers = Inspections.aliInspections(project) { it.tool is AliBaseInspection } val psiElement = e.getData(CommonDataKeys.PSI_ELEMENT) val psiFile = e.getData(CommonDataKeys.PSI_FILE) val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE) ... createContext( toolWrappers, managerEx, element, projectDir, analysisScope ).doInspections(analysisScope) }

      這是一個基于 kotlin 語言開發的插件代碼邏輯,它通過 actionPerformed 方法獲取到工程信息、類信息等,接下來就可以執行代碼檢查了 doInspections

      3. 規約 p3c-pmd

      當我們再往下翻看閱讀的時候,就看到了一個關于 pmd 的東西。PMD 是一款采用 BSD 協議發布的Java 程序靜態代碼檢查工具,當使用PMD規則分析Java源碼時,PMD首先利用JavaCC和EBNF文法產生了一個語法分析器,用來分析普通文本形式的Java代碼,產生符合特定語法結構的語法,同時又在JavaCC的基礎上添加了語義的概念即JJTree,通過JJTree的一次轉換,這樣就將Java代碼轉換成了一個AST,AST是Java符號流之上的語義層,PMD把AST處理成一個符號表。然后編寫PMD規則,一個PMD規則可以看成是一個Visitor,通過遍歷AST找出多個對象之間的一種特定模式,即代碼所存在的問題。該軟件功能強大,掃描效率高,是 Java 程序員 debug 的好幫手。

      那么 p3c-pmd 是什么呢?

      ViolationUtils.addViolationWithPrecisePosition(this, node, data, I18nResources.getMessage("java.naming.ClassNamingShouldBeCamelRule.violation.msg", node.getImage()));

      p3c-pmd 插件是基于 PMD 實現的,更具體的來說是基于 pmd-java 的,因為 PMD 不僅支持 Java 代碼分析,還支持其他多種語言。

      具體自定義規則的方式,通過自定義Java類和XPATH規則實現。

      p3c 插件,是怎么檢查出你那屎山的代碼?

      四、規約監測案例

      講道理,說一千道一萬,還得是拿出代碼跑一下,才知道 PMD 具體是什么個樣子。

      1. 測試工程

      guide-pmd └── src ├── main │ ├── java │ │ └── cn.itedus.guide.pmd.rule │ │ ├── naming │ │ │ ├── ClassNamingShouldBeCamelRule.java │ │ │ ├── ConstantFieldShouldBeUpperCaseRule.java │ │ │ └── LowerCamelCaseVariableNamingRule.java │ │ ├── utils │ │ │ ├── StringAndCharConstants.java │ │ │ └── ViolationUtils.java │ │ └── I18nResources │ └── resources │ ├── rule │ │ └── ali-naming.xml │ ├── messages.xml │ └── namelist.properties └── test └── java └── cn.itedus.demo.test ├── ApiTest.java └── TErrDto.java

      源碼:https://github.com/fuzhengwei/guide-pmd

      這是一個類似 p3c-pmd 的測試工程,通過自行擴展重寫代碼監測規約的方式,來處理自己關于代碼的審核標準處理。

      naming 下的類是用于處理一些和名稱相關的規則,類名、屬性名、方法名等

      resources 下 ali-naming.xml 是規約的配置文件

      2. 駝峰命名規約

      public class ClassNamingShouldBeCamelRule extends AbstractJavaRule { private static final Pattern PATTERN = Pattern.compile("^I?([A-Z][a-z0-9]+)+(([A-Z])|(DO|DTO|VO|DAO|BO|DAOImpl|YunOS|AO|PO))?$"); @Override public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { if (PATTERN.matcher(node.getImage()).matches()) { return super.visit(node, data); } ViolationUtils.addViolationWithPrecisePosition(this, node, data, I18nResources.getMessage("java.naming.ClassNamingShouldBeCamelRule.violation.msg", node.getImage())); return super.visit(node, data); } }

      通過繼承 PMD 提供的 AbstractJavaRule 抽象類,重寫 visit 方法,使用正則的方式進行驗證。

      visit 方法都入參類型非常多,分別用于處理類、接口、方法、代碼等各項內容的監測處理,只要重寫需要的方法,在里面進行自己都處理就可以。

      ClassNamingShouldBeCamelRule、ConstantFieldShouldBeUpperCaseRule、LowerCamelCaseVariableNamingRule 三個類都功能類似,這里就不一一展示了,可以直接參考源碼。

      3. ali-naming.xml 配置

      3

      在 ali-naming.xml 用于配置規約處理類、priority 級別、message 提醒文字。

      同時還可以配置代碼示例,使用 標簽,在里面寫好標準代碼即可。

      4. 測試驗證規約

      問題類示例

      public class TErrDto { public static final Long max = 50000L; public void QueryUserInfo(){ boolean baz = true; while (baz) baz = false; } }

      單元測試

      @Test public void test_naming(){ String[] str = { "-d", "E:\\itstack\\git\\github.com\\guide-pmd\\src\\test\\java\\cn\\itedus\\demo\\test\\TErrDto.java", "-f", "text", "-R", "E:\\itstack\\git\\github.com\\guide-pmd\\src\\main\\resources\\rule\\ali-naming.xml" // "category/java/codestyle.xml" }; PMD.main(str); }

      規約的測試驗證可以直接使用 PMD.main 方法,在方法中提供字符串數組入參,這里的代碼監測地址和規約配置需要是絕對路徑。

      測試結果

      TErrDto.java:3: 【TErrDto】不符合UpperCamelCase命名風格 TErrDto.java:5: 常量【max】命名應全部大寫并以下劃線分隔 TErrDto.java:7: 方法名【QueryUserInfo】不符合lowerCamelCase命名風格 Process finished with exit code 4

      從測試結果可以看到,我們寫的三個代碼規約分別監測出了代碼的命名風格、常量大寫、方法名不符合駝峰標識。

      同時你還可以測試 category/java/codestyle.xml 這個是 PMD 自身提供好的規約監測。

      五、擴展了解 Sonar

      其實有了 PMD 靜態代碼檢查規約,能做都事情就很多,不是只對正在寫的代碼進行檢查,還可以對不同階段的代碼進行分析和風險提醒,比如:準備提測階段、已經上線完成,都可以做相應的監測處理。

      而 Sonar 就是一個這樣都工具,它是一個Web系統,可以展現靜態代碼掃描的結果,結果是可以自定義的,支持多種語言的原理是它的擴展性。https://www.sonarqube.org/

      不遵循代碼標準:sonar可以通過PMD,CheckStyle,Findbugs等等代碼規則檢測工具規范代碼編寫。

      潛在的缺陷:sonar可以通過PMD,CheckStyle,Findbugs等等代碼規則檢測工具檢 測出潛在的缺陷。

      糟糕的復雜度分布:文件、類、方法等,如果復雜度過高將難以改變,這會使得開發人員 難以理解它們, 且如果沒有自動化的單元測試,對于程序中的任何組件的改變都將可能導致需要全面的回歸測試。

      重復:顯然程序中包含大量復制粘貼的代碼是質量低下的,sonar可以展示 源碼中重復嚴重的地方。

      注釋不足或者過多:沒有注釋將使代碼可讀性變差,特別是當不可避免地出現人員變動 時,程序的可讀性將大幅下降 而過多的注釋又會使得開發人員將精力過多地花費在閱讀注釋上,亦違背初衷。

      缺乏單元測試:sonar可以很方便地統計并展示單元測試覆蓋率。

      糟糕的設計:通過sonar可以找出循環,展示包與包、類與類之間的相互依賴關系,可以檢測自定義的架構規則 通過sonar可以管理第三方的jar包,可以利用LCOM4檢測單個任務規則的應用情況, 檢測耦合。

      提高代碼質量:了解自己在編碼過程中犯過的錯誤,讓自己的代碼更具有可讀性和維護性。

      六、總結

      PMD 是一款采用 BSD 協議的代碼檢查工具,你可以擴展實現為自己的標準和規范以及完善個性的提醒和修復操作。

      另外基于 IDEA 插件實現的代碼檢查或者有審計要求的處理,也可以基于 IDEA 插件做更多的擴展,比如提醒修復、提供修復操作、自身業務邏輯的檢查。例如momo開源庫下的一款IDEA靜態代碼安全審計及漏洞一鍵修復插件 https://github.com/momosecurity/momo-code-sec-inspector-java

      這里補充一點,kotlin 語言可以在 IDEA 中轉換為 Java 語言,這樣你在閱讀類似這樣的代碼時候,如果不好看懂也可以轉換一下在閱讀。此外 IDEA 插件開發需要基于 Gradle 或者本身提供都模版進行創建,如果感興趣也可以閱讀我寫的 IDEA 插件開發文章。

      七、系列推薦

      基于IDEA插件開發和字節碼插樁技術,實現研發交付質量自動分析

      技術調研,IDEA 插件怎么開發「腳手架、低代碼可視化編排、接口生成測試」?

      《SpringBoot 中間件設計和開發》

      筆記整理:技術架構涵蓋內容和演變過程總結

      給學習加點實踐,開發一個分布式IM(即時通信)系統!

      IDE Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel2007雙軸折線圖怎么做
      下一篇:wps導入什么了格式數據
      相關文章
      精品亚洲AV无码一区二区| 久久99亚洲网美利坚合众国| 中文字幕第13亚洲另类| 亚洲一级高清在线中文字幕| 亚洲综合精品香蕉久久网97| 亚洲成A人片在线观看WWW| 亚洲av日韩av欧v在线天堂| 国产精品亚洲AV三区| 亚洲一区二区三区国产精华液| 亚洲白色白色在线播放| 老司机亚洲精品影院| 亚洲性猛交XXXX| 国产亚洲视频在线观看| 亚洲中文字幕AV在天堂| 亚洲综合色成在线播放| 亚洲精品乱码久久久久蜜桃| 亚洲一区二区三区在线观看网站| 亚洲高清无在码在线电影不卡| 亚洲日韩涩涩成人午夜私人影院| 亚洲xxxx视频| 亚洲一区二区三区高清| 亚洲午夜精品一级在线播放放| 亚洲乱码av中文一区二区| 久久亚洲精品人成综合网| 亚洲成av人片在线观看天堂无码| 亚洲精品熟女国产| 亚洲精品无码AV人在线播放| 日韩亚洲人成在线综合| 性xxxx黑人与亚洲| 亚洲国产成人无码AV在线影院| 亚洲网站在线观看| 亚洲乱码日产精品一二三| 亚洲精品tv久久久久| 久久精品国产亚洲77777| ZZIJZZIJ亚洲日本少妇JIZJIZ | 日韩亚洲不卡在线视频中文字幕在线观看| 久久亚洲高清综合| 国产偷国产偷亚洲高清人| 亚洲免费综合色在线视频| 国产亚洲国产bv网站在线| 337p日本欧洲亚洲大胆色噜噜|