作為程序猿,每天都在寫(xiě)代碼,但是有沒(méi)有想過(guò)通過(guò)代碼對(duì)寫(xiě)好的代碼”動(dòng)點(diǎn)手腳”呢?今天就與大家分享——
先拋一個(gè)問(wèn)題:如何將圖一代碼改寫(xiě)為圖二?
此題需要把代碼中和程序邏輯無(wú)關(guān)的字符串提取出來(lái),替換為id。比如個(gè)推日志輸出類,縮短日志描述信息后,輸出的日志就隨之變短,根據(jù)映射表可以恢復(fù)真實(shí)原始日志。
你可能會(huì)想通過(guò)萬(wàn)能的“正則表達(dá)式”匹配替換,但當(dāng)代碼較為復(fù)雜時(shí)(如下圖所示),使用“正則表達(dá)法”則會(huì)將問(wèn)題復(fù)雜化,難以確保所有代碼的完美覆蓋并匹配。若通過(guò)AST語(yǔ)法樹(shù),可以很好地解決此問(wèn)題。
AST(Abstract syntax tree)即為“抽象語(yǔ)法樹(shù)”,簡(jiǎn)稱語(yǔ)法樹(shù),指代碼在計(jì)算機(jī)內(nèi)存的一種樹(shù)狀數(shù)據(jù)結(jié)構(gòu),便于計(jì)算機(jī)理解和閱讀。
一般只有語(yǔ)言的編譯器開(kāi)發(fā)人員或者從事語(yǔ)言設(shè)計(jì)的人員才涉及到語(yǔ)法樹(shù)的提取和處理,所以很多人會(huì)對(duì)這個(gè)概念比較陌生。
上圖即為語(yǔ)法樹(shù),左邊樹(shù)的節(jié)點(diǎn)對(duì)應(yīng)右邊相同顏色覆蓋的代碼塊。
眾所周知,Java 編譯流程(上圖)中也有對(duì)AST語(yǔ)法樹(shù)的提取處理,那是否可以在此環(huán)節(jié)操作語(yǔ)法樹(shù)呢?由于編譯鏈代碼棧太深,鮮有對(duì)外的接口和文檔,使得其可操作性不強(qiáng)。不過(guò),如果采用迂回戰(zhàn)術(shù)如下圖所示,可以對(duì)其進(jìn)行操作。
個(gè)推log-rewrite項(xiàng)目改寫(xiě)日志,就是用AST語(yǔ)法樹(shù)進(jìn)行的,流程圖如下圖所示。
先把所有源碼解析為AST語(yǔ)法樹(shù),遍歷每一個(gè)編譯單元與單元的類聲明,在類聲明里根據(jù)日志方法的簽名找到所有的方法調(diào)用,然后遍歷每個(gè)方法調(diào)用,將方法調(diào)用的第二個(gè)參數(shù)表達(dá)式放入遞歸方法,對(duì)字符串字面值進(jìn)行改寫(xiě)。
對(duì)應(yīng)的代碼較為簡(jiǎn)短, 使用github的 Netflix-Skunkworks/rewrite開(kāi)源庫(kù)與kotlin語(yǔ)言,能讀懂Java的你也一定能讀明白。
如果想將日志恢復(fù)原樣,可根據(jù)前綴、后綴定制正則表達(dá)式,逐行匹配替換。如下圖所示。
1、 編譯工具從ant到gradle的切換
此項(xiàng)目起步于ant主流時(shí)期,隨著技術(shù)日漸成熟,gradle逐漸取代了ant的位置,演變成官方的編譯打包方式。因?yàn)闅v史原因,若直接將上圖類似預(yù)編譯的代碼切換到gradle較為棘手,通過(guò)AST語(yǔ)法樹(shù)重寫(xiě),再用gradle編譯,就可以解決此問(wèn)題。
上圖的#debug和#mdebug指令,也可以通過(guò)AST改寫(xiě)之后再進(jìn)行編譯。
2、 自動(dòng)靜態(tài)埋點(diǎn)
代碼中需要運(yùn)營(yíng)統(tǒng)計(jì)、數(shù)據(jù)分析等,需要通過(guò)代碼埋點(diǎn)進(jìn)行用戶行為數(shù)據(jù)收集。傳統(tǒng)的做法是手動(dòng)在代碼中添加埋點(diǎn)代碼,但此過(guò)程較為繁瑣,可能會(huì)對(duì)業(yè)務(wù)代碼造成干擾,倘若通過(guò)改寫(xiě)AST語(yǔ)法樹(shù),在編譯打包期添加這種類似的埋點(diǎn)代碼,就可減少不必要的繁瑣過(guò)程,使其更加高效。
最后附推薦操作AST類庫(kù)鏈接&完整項(xiàng)目源碼地址,希望可以幫助大家打開(kāi)腦洞,設(shè)想更多的應(yīng)用場(chǎng)景。
推薦操作AST類庫(kù)鏈接
https://github.com/Netflix-Skunkworks/rewrite
https://github.com/Javaparser/Javaparser
https://github.com/antlr/antlr4
完整項(xiàng)目源碼地址如下,歡迎fork&start
https://github.com/foxundermoon/log-rewrite
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)站欄目:教你如何用AST語(yǔ)法樹(shù)對(duì)代碼“動(dòng)手腳”-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://www.rwnh.cn/article22/doeojc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、網(wǎng)站維護(hù)、移動(dòng)網(wǎng)站建設(shè)、App開(kāi)發(fā)、網(wǎng)站導(dǎo)航、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容