自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

P3c 插件,是怎么檢查出你不靠譜的代碼?

開發(fā) 開發(fā)工具
雖然我們都被稱為碼農(nóng),也都是寫著代碼,但因為所處場景需求的不同,所以各類碼農(nóng)也都做著不一樣都事情。

[[426220]]

本文轉(zhuǎn)載自微信公眾號「bugstack蟲洞?!梗髡咝「蹈纭^D(zhuǎn)載本文請聯(lián)系bugstack蟲洞棧公眾號。

一、前言

你會對你用到都技術(shù),好奇嗎?

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

有些人統(tǒng)一規(guī)范、有些人開發(fā)組件、有些人編寫業(yè)務、有些人倒騰驗證,但越是工作內(nèi)容簡單如CRUD一樣的碼農(nóng),用到別人提供好的東西卻是越多。一會安裝個插件、一會引入個Jar包、一會調(diào)別人個接口,而自己的工作就像是裝配工,東拼拼西湊湊,就把產(chǎn)品需求寫完了。

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

二、P3C 插件是什么

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

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

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

  • 在遵守開發(fā)手冊標準并按照插件檢查都情況下,還是可以非常好的統(tǒng)一編碼標準和風格都,也能剔除掉一些潛在都風險。
  • 如果你是新手編程用戶或者想寫出標準都代碼,那么非常建議你按照這樣都插件來輔助自己做代碼開發(fā)。當然如果你所在的公司也有相應都標準手冊和插件,也可以按照后遵守它都約定的。

三、P3C 插件源碼

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

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

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

  • 插件源碼:https://github.com/alibaba/p3c/blob/master/idea-plugin
  • 規(guī)約源碼:https://github.com/alibaba/p3c/tree/master/p3c-pmd

1. 插件配置 p3c.xml

  1. <action class="com.alibaba.p3c.idea.action.AliInspectionAction" id="AliP3CInspectionAction" 
  2.         popup="true" text="編碼規(guī)約掃描" icon="P3cIcons.ANALYSIS_ACTION"
  3.     <keyboard-shortcut keymap="$default" 
  4.                        first-keystroke="shift ctrl alt J"/> 
  5.     <add-to-group group-id="MainToolBar" anchor="last"/> 
  6.     <add-to-group group-id="ProjectViewPopupMenu" anchor="last"/> 
  7.     <add-to-group group-id="ChangesViewPopupMenu" anchor="last"/> 
  8.     <add-to-group group-id="EditorPopupMenu" anchor="last"/> 
  9. </action

 

  • 翻看源碼最重要是要找到入口,這個入口通常也是你在使用插件、程序、接口等時候,最直接進入都那部分。
  • 那么我們在使用 P3C 插件的時候,最明顯的就是 編碼規(guī)約掃描 通過源碼中找到這個關(guān)鍵字,看它都涉及了哪個類都配置。
  • action 是 IDEA 插件中用于配置窗體事件入口都地方,以及把這個操作配置到哪個按鈕下和對應都快捷鍵。

2. 編碼規(guī)約掃描( AliInspectionAction)

  1. class AliInspectionAction : AnAction() { 
  2.  
  3.     override fun actionPerformed(e: AnActionEvent) { 
  4.         val project = e.project ?: return 
  5.         val analysisUIOptions = ServiceManager.getService(project, AnalysisUIOptions::class.java)!! 
  6.         analysisUIOptions.GROUP_BY_SEVERITY = true 
  7.  
  8.         val managerEx = InspectionManager.getInstance(project) as InspectionManagerEx 
  9.         val toolWrappers = Inspections.aliInspections(project) { 
  10.             it.tool is AliBaseInspection 
  11.         } 
  12.         val psiElement = e.getData<PsiElement>(CommonDataKeys.PSI_ELEMENT) 
  13.         val psiFile = e.getData<PsiFile>(CommonDataKeys.PSI_FILE) 
  14.         val virtualFile = e.getData<VirtualFile>(CommonDataKeys.VIRTUAL_FILE) 
  15.          
  16.   ... 
  17.    
  18.   createContext( 
  19.      toolWrappers, managerEx, element, 
  20.      projectDir, analysisScope 
  21.   ).doInspections(analysisScope) 
  22. }   

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

3. 規(guī)約 p3c-pmd

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

那么 p3c-pmd 是什么呢?

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

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

具體自定義規(guī)則的方式,通過自定義Java類和XPATH規(guī)則實現(xiàn)。

四、規(guī)約監(jiān)測案例

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

1. 測試工程

  1. guide-pmd 
  2. └── src 
  3.     ├── main 
  4.     │   ├── java 
  5.     │   │   └── cn.itedus.guide.pmd.rule 
  6.     │   │       ├── naming 
  7.     │   │       │   ├── ClassNamingShouldBeCamelRule.java 
  8.     │   │       │   ├── ConstantFieldShouldBeUpperCaseRule.java 
  9.     │   │       │   └── LowerCamelCaseVariableNamingRule.java 
  10.     │   │       ├── utils 
  11.     │   │       │   ├── StringAndCharConstants.java 
  12.     │   │       │   └── ViolationUtils.java     
  13.     │   │       └── I18nResources 
  14.     │   └── resources 
  15.     │       ├── rule  
  16.     │       │   └── ali-naming.xml   
  17.     │       ├── messages.xml    
  18.     │       └── namelist.properties   
  19.     └── test 
  20.         └── java 
  21.             └── cn.itedus.demo.test 
  22.                 ├── ApiTest.java 
  23.                 └── TErrDto.java 
  • 源碼:https://github.com/fuzhengwei/guide-pmd

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

  • naming 下的類是用于處理一些和名稱相關(guān)的規(guī)則,類名、屬性名、方法名等
  • resources 下 ali-naming.xml 是規(guī)約的配置文件

2. 駝峰命名規(guī)約

  1. public class ClassNamingShouldBeCamelRule extends AbstractJavaRule { 
  2.  
  3.     private static final Pattern PATTERN 
  4.             = Pattern.compile("^I?([A-Z][a-z0-9]+)+(([A-Z])|(DO|DTO|VO|DAO|BO|DAOImpl|YunOS|AO|PO))?$"); 
  5.  
  6.     @Override 
  7.     public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { 
  8.         if (PATTERN.matcher(node.getImage()).matches()) { 
  9.             return super.visit(node, data); 
  10.         } 
  11.          
  12.         ViolationUtils.addViolationWithPrecisePosition(this, node, data, 
  13.                 I18nResources.getMessage("java.naming.ClassNamingShouldBeCamelRule.violation.msg"
  14.                         node.getImage())); 
  15.  
  16.         return super.visit(node, data); 
  17.     } 
  • 通過繼承 PMD 提供的 AbstractJavaRule 抽象類,重寫 visit 方法,使用正則的方式進行驗證。
  • visit 方法都入?yún)㈩愋头浅6?,分別用于處理類、接口、方法、代碼等各項內(nèi)容的監(jiān)測處理,只要重寫需要的方法,在里面進行自己都處理就可以。
  • ClassNamingShouldBeCamelRule、ConstantFieldShouldBeUpperCaseRule、LowerCamelCaseVariableNamingRule 三個類都功能類似,這里就不一一展示了,可以直接參考源碼。

3. ali-naming.xml 配置

  1. <rule name="ClassNamingShouldBeCamelRule" 
  2.       language="java" 
  3.       since="1.6" 
  4.       message="java.naming.ClassNamingShouldBeCamelRule.rule.msg" 
  5.       class="cn.itedus.guide.pmd.rule.naming.ClassNamingShouldBeCamelRule"
  6.     <priority>3</priority> 
  7. </rule
  • 在 ali-naming.xml 用于配置規(guī)約處理類、priority 級別、message 提醒文字。
  • 同時還可以配置代碼示例,使用 標簽,在里面寫好標準代碼即可。

4. 測試驗證規(guī)約

問題類示例

  1. public class TErrDto { 
  2.  
  3.     public static final Long max = 50000L; 
  4.  
  5.     public void QueryUserInfo(){ 
  6.         boolean baz = true
  7.         while (baz) 
  8.             baz = false
  9.     } 
  10.  

單元測試

  1. @Test 
  2. public void test_naming(){ 
  3.     String[] str = { 
  4.             "-d"
  5.             "E:\\itstack\\git\\github.com\\guide-pmd\\src\\test\\java\\cn\\itedus\\demo\\test\\TErrDto.java"
  6.             "-f"
  7.             "text"
  8.             "-R"
  9.             "E:\\itstack\\git\\github.com\\guide-pmd\\src\\main\\resources\\rule\\ali-naming.xml" 
  10.             // "category/java/codestyle.xml" 
  11.     }; 
  12.     PMD.main(str); 
  • 規(guī)約的測試驗證可以直接使用 PMD.main 方法,在方法中提供字符串數(shù)組入?yún)ⅲ@里的代碼監(jiān)測地址和規(guī)約配置需要是絕對路徑。

測試結(jié)果

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

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

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

五、擴展了解 Sonar

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

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

  • 不遵循代碼標準:sonar可以通過PMD,CheckStyle,Findbugs等等代碼規(guī)則檢測工具規(guī)范代碼編寫。
  • 潛在的缺陷:sonar可以通過PMD,CheckStyle,Findbugs等等代碼規(guī)則檢測工具檢 測出潛在的缺陷。
  • 糟糕的復雜度分布:文件、類、方法等,如果復雜度過高將難以改變,這會使得開發(fā)人員 難以理解它們, 且如果沒有自動化的單元測試,對于程序中的任何組件的改變都將可能導致需要全面的回歸測試。
  • 重復:顯然程序中包含大量復制粘貼的代碼是質(zhì)量低下的,sonar可以展示 源碼中重復嚴重的地方。
  • 注釋不足或者過多:沒有注釋將使代碼可讀性變差,特別是當不可避免地出現(xiàn)人員變動 時,程序的可讀性將大幅下降 而過多的注釋又會使得開發(fā)人員將精力過多地花費在閱讀注釋上,亦違背初衷。
  • 缺乏單元測試:sonar可以很方便地統(tǒng)計并展示單元測試覆蓋率。
  • 糟糕的設計:通過sonar可以找出循環(huán),展示包與包、類與類之間的相互依賴關(guān)系,可以檢測自定義的架構(gòu)規(guī)則 通過sonar可以管理第三方的jar包,可以利用LCOM4檢測單個任務規(guī)則的應用情況, 檢測耦合。
  • 提高代碼質(zhì)量:了解自己在編碼過程中犯過的錯誤,讓自己的代碼更具有可讀性和維護性。

六、總結(jié)

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

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

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

 

責任編輯:武曉燕 來源: bugstack蟲洞棧
相關(guān)推薦

2022-12-08 09:01:58

2014-08-04 09:30:43

170

2011-12-26 14:11:47

三星Android

2012-10-22 11:14:05

SDNOpenFlow網(wǎng)絡管理

2017-09-05 15:27:33

View Api23Api24

2012-11-23 12:38:12

Wi-FiWLAN

2013-12-03 10:16:43

移動開放

2011-12-29 16:29:51

投影儀用戶體驗

2012-12-14 13:31:02

2011-04-29 14:48:50

國產(chǎn)打印機惠普打印機

2012-09-19 14:33:51

創(chuàng)業(yè)程序員創(chuàng)業(yè)成功

2023-06-28 07:04:55

攢機主板芯片

2018-11-01 13:57:25

AR醫(yī)療患者

2020-07-17 11:28:24

App信息泄露個人信息

2013-11-26 13:31:11

IT商業(yè)

2012-08-14 10:15:46

程序員

2021-09-14 07:08:49

iPhone 13衛(wèi)星上網(wǎng)蘋果

2014-12-03 10:39:56

世紀互聯(lián)公有云

2020-07-28 15:18:52

Gartner信息安全網(wǎng)絡安全

2013-03-07 11:33:46

App移動應用盈利
點贊
收藏

51CTO技術(shù)棧公眾號