掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
你會(huì)對(duì)你用到都技術(shù),好奇嗎?

在霍州等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需定制開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都營(yíng)銷網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站制作,霍州網(wǎng)站建設(shè)費(fèi)用合理。
雖然我們都被稱為碼農(nóng),也都是寫著代碼,但因?yàn)樗巿?chǎng)景需求的不同,所以各類碼農(nóng)也都做著不一樣都事情。
有些人統(tǒng)一規(guī)范、有些人開發(fā)組件、有些人編寫業(yè)務(wù)、有些人倒騰驗(yàn)證,但越是工作內(nèi)容簡(jiǎn)單如CRUD一樣的碼農(nóng),用到別人提供好的東西卻是越多。一會(huì)安裝個(gè)插件、一會(huì)引入個(gè)Jar包、一會(huì)調(diào)別人個(gè)接口,而自己的工作就像是裝配工,東拼拼西湊湊,就把產(chǎn)品需求寫完了。
壞了,這么干可能幾年下來(lái),也不會(huì)有什么技術(shù)上都突破。因?yàn)槟銓?duì)那些使用都技術(shù)不好奇,不想知道它們是怎么實(shí)現(xiàn)的。就像阿里的P3C插件,是怎么檢查代碼分析出來(lái)我寫的拉胯的呢?
P3C 是阿里開源代碼庫(kù)的插件工程名稱,它以阿里巴巴Java開發(fā)手冊(cè)為標(biāo)準(zhǔn),用于監(jiān)測(cè)代碼質(zhì)量的 IDEA/Eclipse 插件。
插件安裝完成后,就可以按照編程規(guī)約,靜態(tài)分析代碼中出現(xiàn)的代碼:命名風(fēng)格、常量定義、集合處理、并發(fā)處理、OOP、控制語(yǔ)句、注釋、異常等各項(xiàng)潛在風(fēng)險(xiǎn),同時(shí)會(huì)給出一些優(yōu)化操作和實(shí)例。
在最開始使用這類代碼檢查都插件的時(shí)候,就非常好奇它是怎么發(fā)現(xiàn)我的屎山代碼的,用了什么樣都技術(shù)原理呢,如果我能分析下是不是也可以把這樣都技術(shù)手段用到其他地方。
在分析這樣一個(gè)代碼檢查插件前,先思考要從 IDEA 插件都源碼查起,看看它是什么個(gè)邏輯,之后分析具體是如何使用都。其實(shí)這與一些其他的框架性源碼學(xué)習(xí)都是類似的,拿到官網(wǎng)都文檔、Git*** 對(duì)應(yīng)的源碼,按照步驟進(jìn)行構(gòu)建、部署、測(cè)試、調(diào)試、分析,進(jìn)而找到核心原理。
P3C 以 IDEA 插件開發(fā)為例,主要涉及到插件部分和規(guī)約部分,因?yàn)槭前岩?guī)約檢查的能力與插件技術(shù)結(jié)合,所以會(huì)涉及到一些 IDEA 開發(fā)的技術(shù)。另外 P3C 插件涉及到都技術(shù)語(yǔ)言不只是 Java 還有一部分 kotlin 它是一種在 Java 虛擬機(jī)上運(yùn)行的靜態(tài)類型編程語(yǔ)言。
popup="true" text="編碼規(guī)約掃描" icon="P3cIcons.ANALYSIS_ACTION">
first-keystroke="shift ctrl alt J"/>
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)
} 當(dāng)我們?cè)偻路撮喿x的時(shí)候,就看到了一個(gè)關(guān)于 pmd 的東西。PMD 是一款采用 BSD 協(xié)議發(fā)布的Java 程序靜態(tài)代碼檢查工具,當(dāng)使用PMD規(guī)則分析Java源碼時(shí),PMD首先利用JavaCC和EBNF文法產(chǎn)生了一個(gè)語(yǔ)法分析器,用來(lái)分析普通文本形式的Java代碼,產(chǎn)生符合特定語(yǔ)法結(jié)構(gòu)的語(yǔ)法,同時(shí)又在JavaCC的基礎(chǔ)上添加了語(yǔ)義的概念即JJTree,通過(guò)JJTree的一次轉(zhuǎn)換,這樣就將Java代碼轉(zhuǎn)換成了一個(gè)AST,AST是Java符號(hào)流之上的語(yǔ)義層,PMD把AST處理成一個(gè)符號(hào)表。然后編寫PMD規(guī)則,一個(gè)PMD規(guī)則可以看成是一個(gè)Visitor,通過(guò)遍歷AST找出多個(gè)對(duì)象之間的一種特定模式,即代碼所存在的問(wèn)題。該軟件功能強(qiáng)大,掃描效率高,是 Java 程序員 debug 的好幫手。
那么 p3c-pmd 是什么呢?
ViolationUtils.addViolationWithPrecisePosition(this, node, data,
I18nResources.getMessage("java.naming.ClassNamingShouldBeCamelRule.violation.msg",
node.getImage()));
講道理,說(shuō)一千道一萬(wàn),還得是拿出代碼跑一下,才知道 PMD 具體是什么個(gè)樣子。
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
這是一個(gè)類似 p3c-pmd 的測(cè)試工程,通過(guò)自行擴(kuò)展重寫代碼監(jiān)測(cè)規(guī)約的方式,來(lái)處理自己關(guān)于代碼的審核標(biāo)準(zhǔn)處理。
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);
}
}language="java"
since="1.6"
message="java.naming.ClassNamingShouldBeCamelRule.rule.msg"
class="cn.itedus.guide.pmd.rule.naming.ClassNamingShouldBeCamelRule">
3
問(wèn)題類示例
public class TErrDto {
public static final Long max = 50000L;
public void QueryUserInfo(){
boolean baz = true;
while (baz)
baz = false;
}
}單元測(cè)試
@Test
public void test_naming(){
String[] str = {
"-d",
"E:\\itstack\\git\\**.com\\guide-pmd\\src\\test\\java\\cn\\itedus\\demo\\test\\TErrDto.java",
"-f",
"text",
"-R",
"E:\\itstack\\git\\**.com\\guide-pmd\\src\\main\\resources\\rule\\ali-naming.xml"
// "category/java/codestyle.xml"
};
PMD.main(str);
}
測(cè)試結(jié)果
TErrDto.java:3: 【TErrDto】不符合UpperCamelCase命名風(fēng)格
TErrDto.java:5: 常量【max】命名應(yīng)全部大寫并以下劃線分隔
TErrDto.java:7: 方法名【QueryUserInfo】不符合lowerCamelCase命名風(fēng)格
Process finished with exit code
其實(shí)有了 PMD 靜態(tài)代碼檢查規(guī)約,能做都事情就很多,不是只對(duì)正在寫的代碼進(jìn)行檢查,還可以對(duì)不同階段的代碼進(jìn)行分析和風(fēng)險(xiǎn)提醒,比如:準(zhǔn)備提測(cè)階段、已經(jīng)上線完成,都可以做相應(yīng)的監(jiān)測(cè)處理。
而 Sonar 就是一個(gè)這樣都工具,它是一個(gè)Web系統(tǒng),可以展現(xiàn)靜態(tài)代碼掃描的結(jié)果,結(jié)果是可以自定義的,支持多種語(yǔ)言的原理是它的擴(kuò)展性。https://www.sonarqube.org/

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流