摘要:最后提供一段我用寫(xiě)的代碼供參考行就能把任意代碼結(jié)構(gòu)轉(zhuǎn)換成輸出使用了庫(kù)利用強(qiáng)大的屬性描述符,寫(xiě)出通用的轉(zhuǎn)換代碼,避免了給每個(gè)結(jié)點(diǎn)類寫(xiě)對(duì)應(yīng)的轉(zhuǎn)換代碼幾十種結(jié)點(diǎn)類,要死啊。
另載于 http://www.qingjingjie.com/blogs/4
上篇介紹的形形色色的語(yǔ)法元素大概讓人眼花繚亂了,而且每種元素都對(duì)應(yīng)一個(gè)Java類。知道是一回事,使用就是另一回事了,這么多個(gè)類,要給每個(gè)類寫(xiě)對(duì)應(yīng)的處理代碼,不勝其煩。ASTVisitor雖然能自動(dòng)遍歷語(yǔ)法樹(shù),但是并不能幫你處理每一種結(jié)點(diǎn)。
好在JDT提供了更加抽象的屬性描述符(property descriptor),寥寥幾個(gè)類就能掌控所有Java語(yǔ)法。用術(shù)語(yǔ)來(lái)說(shuō),上篇的那些類屬于異構(gòu)AST,本篇講的是同構(gòu)AST。
對(duì)任何AST結(jié)點(diǎn)都可調(diào)用方法structuralPropertiesForType(),你會(huì)得到List
StructuralPropertyDescriptor 是一個(gè)抽象類,有三個(gè)子類:SimplePropertyDescriptor, ChildPropertyDescriptor, ChildListPropertyDescriptor。這些東西是元數(shù)據(jù),用來(lái)描述各種語(yǔ)法元素的固有結(jié)構(gòu),使用它們有種在用Java反射的感覺(jué)。
SimplePropertyDescriptor 表示這個(gè)字段存放的不是AST結(jié)點(diǎn),而是個(gè)值,可能是int, String,Operator之類的,SimplePropertyDescriptor.valueType 能告訴我們這個(gè)值是什么類型。
ChildPropertyDescriptor 表示這個(gè)字段存放的是一個(gè)AST結(jié)點(diǎn),比如我們解析了一個(gè)class,得到typeDeclaration結(jié)點(diǎn),然后調(diào)用typeDeclaration.structuralPropertiesForType(),得到的list中有一項(xiàng)就是typeName的描述符,嗯,就是AbstractTypeDeclaration類的typeName字段,字段類型為SimpleName。
ChildListPropertyDescriptor 表示這個(gè)字段存放的是一組AST結(jié)點(diǎn)! 比如AbstractTypeDeclaration擁有一組bodyDeclarations,而CompilationUnit則擁有一組imports。bodyDeclarations和imports都是List!
有了描述符能做什么呢? 可以自由訪問(wèn)一棵語(yǔ)法樹(shù)了。
我們來(lái)想象一個(gè)流程:你有一個(gè)java文件,你把它交給JDT的parser,解析出一個(gè)CompilationUnit cu,也就是一棵語(yǔ)法樹(shù)的根結(jié)點(diǎn)。調(diào)用cu.structuralPropertiesForType(),得到描述符的list,循環(huán)遍歷list,對(duì)每個(gè)描述符prop,用instanceof判斷具體類型(總共就3個(gè)類型),分別做"不同處理"。
不同處理:instanceof操作發(fā)現(xiàn)某個(gè)描述符是ChildListPropertyDescriptor, 于是你把描述符強(qiáng)轉(zhuǎn)(cast)成該類型,調(diào)用prop.getId()得到"imports",哦,是imports字段啊,調(diào)用prop.getElementType()得到ImportDeclaration.class,確認(rèn)了這一發(fā)現(xiàn)。然后你調(diào)用cu.getStructuralProperty(prop)得到一個(gè)object,你知道它實(shí)際是List
由此你就完成了一個(gè)分析流程。因?yàn)椴挥藐P(guān)心具體的結(jié)點(diǎn)類型,所以你可以方便地進(jìn)行一些宏觀、抽象的分析。
最后提供一段我用Scala寫(xiě)的代碼供參考(50行就能把任意Java代碼結(jié)構(gòu)轉(zhuǎn)換成JSON輸出, 使用了lift json庫(kù)):
https://github.com/sorra/Lanka/blob/fa52cdaa2f94aadfcc29f8be2711a88da3c8cbb3/src/sorra/lanka/json/MetaConversion.scala
利用強(qiáng)大的屬性描述符,寫(xiě)出通用的JSON轉(zhuǎn)換代碼,避免了給每個(gè)結(jié)點(diǎn)類寫(xiě)對(duì)應(yīng)的JSON轉(zhuǎn)換代碼(幾十種結(jié)點(diǎn)類,要死啊)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/64243.html
摘要:可能很多人和我一樣首次聽(tīng)到前端架構(gòu)這個(gè)詞第一反應(yīng)是前端還有架構(gòu)這一說(shuō)呢在后端開(kāi)發(fā)領(lǐng)域系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵因此架構(gòu)師備受重視早在開(kāi)發(fā)工作啟動(dòng)之前他們就被邀請(qǐng)加入到項(xiàng)目中而且他們會(huì)跟客戶討論即將建成的平臺(tái)的架構(gòu)要求使用還什么技術(shù)棧內(nèi)容類型 可能很多人和我一樣, 首次聽(tīng)到前端架構(gòu)這個(gè)詞, 第一反應(yīng)是: 前端還有架構(gòu)這一說(shuō)呢? 在后端開(kāi)發(fā)領(lǐng)域, 系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵, 因此架構(gòu)師備...
摘要:可能很多人和我一樣首次聽(tīng)到前端架構(gòu)這個(gè)詞第一反應(yīng)是前端還有架構(gòu)這一說(shuō)呢在后端開(kāi)發(fā)領(lǐng)域系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵因此架構(gòu)師備受重視早在開(kāi)發(fā)工作啟動(dòng)之前他們就被邀請(qǐng)加入到項(xiàng)目中而且他們會(huì)跟客戶討論即將建成的平臺(tái)的架構(gòu)要求使用還什么技術(shù)棧內(nèi)容類型 可能很多人和我一樣, 首次聽(tīng)到前端架構(gòu)這個(gè)詞, 第一反應(yīng)是: 前端還有架構(gòu)這一說(shuō)呢? 在后端開(kāi)發(fā)領(lǐng)域, 系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵, 因此架構(gòu)師備...
摘要:可能很多人和我一樣首次聽(tīng)到前端架構(gòu)這個(gè)詞第一反應(yīng)是前端還有架構(gòu)這一說(shuō)呢在后端開(kāi)發(fā)領(lǐng)域系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵因此架構(gòu)師備受重視早在開(kāi)發(fā)工作啟動(dòng)之前他們就被邀請(qǐng)加入到項(xiàng)目中而且他們會(huì)跟客戶討論即將建成的平臺(tái)的架構(gòu)要求使用還什么技術(shù)棧內(nèi)容類型 可能很多人和我一樣, 首次聽(tīng)到前端架構(gòu)這個(gè)詞, 第一反應(yīng)是: 前端還有架構(gòu)這一說(shuō)呢? 在后端開(kāi)發(fā)領(lǐng)域, 系統(tǒng)規(guī)劃和可擴(kuò)展性非常關(guān)鍵, 因此架構(gòu)師備...
摘要:選擇器的最后一部分,也就是選擇器的最右邊在這個(gè)例子中就是部分部分被稱為關(guān)鍵選擇器,它將決定你的選擇器的效率如何是高還是低。因?yàn)樽钣疫叺年P(guān)鍵選擇器是最具體的,也符合上述的選擇器優(yōu)先級(jí)順序。 贊助我以寫(xiě)出更好的文章 如果您覺(jué)得文章對(duì)您有幫助,可以逐個(gè)點(diǎn)擊以下鏈接,類似于Google ads,不需要您付出任何費(fèi)用,每天都可以來(lái)點(diǎn)一次噢,費(fèi)用將由廣告商承擔(dān),give me a cup of c...
閱讀 1964·2021-11-16 11:45
閱讀 3680·2021-09-06 15:02
閱讀 2026·2019-08-30 15:44
閱讀 2291·2019-08-30 11:21
閱讀 1854·2019-08-29 16:31
閱讀 3428·2019-08-29 13:55
閱讀 1900·2019-08-29 12:15
閱讀 3255·2019-08-28 18:05