摘要:操作通常配合來(lái)完成。因?yàn)槭莻€(gè)數(shù)組,因此,我們可以直接使用數(shù)組操作自我毀滅方法極為簡(jiǎn)單,找到要?jiǎng)h除的,執(zhí)行就結(jié)束了。如上述代碼,我們要?jiǎng)h除屬性,代碼如下到目前為止,的我們都介紹完了,下面一篇文章以轉(zhuǎn)小程序?yàn)槔?,我們?lái)實(shí)戰(zhàn)一波。
??通過(guò)前兩篇文章的介紹,大家已經(jīng)了解了Create和Retrieve,我們接著介紹Update和 Remove操作。Update操作通常配合Create來(lái)完成。我們這篇文章主要介紹幾個(gè)常用的NodePath`API:replace、insert、remove`。具體也可以看babel-handbook中的Manipulation章節(jié)。
replaceWith 使用新的節(jié)點(diǎn)進(jìn)行替換 將加法運(yùn)算替換成乘法const code = `const c = a + b` const ast = babylon.parse(code) traverse(ast, { BinaryExpression(path) { // 注意這里要有判斷,否則會(huì)無(wú)限進(jìn)入`BinaryExpression` // https://stackoverflow.com/questions/37539432/babel-maximum-call-stack-size-exceeded-while-using-path-replacewith if (path.node.operator === "+") { path.replaceWith(t.binaryExpression("*", path.node.left, path.node.right)) } } }) console.log(generate(ast, {}, code).code) // const c = a * b;將this.count替換為this.data.count
??轉(zhuǎn)換前后的AST展示如下圖:
??我們需要做的是,找到符合this.count的ThisExpression,然后把它替換為this.data
const code = `this.count` const ast = babylon.parse(code) traverse(ast, { MemberExpression(path) { if ( t.isThisExpression(path.node.object) && t.isIdentifier(path.node.property, { name: "count" }) ) { path .get("object") // 獲取`ThisExpresssion` .replaceWith( t.memberExpression(t.thisExpression(), t.identifier("data")) ) } } }) console.log(generate(ast, {}, code).code) // this.data.count;replaceWithSourceString 直接使用代碼替換
??上個(gè)例子中將this.count替換為this.data.count的部分,通過(guò)t.memberExpression可以構(gòu)造node。更簡(jiǎn)單的操作可以直接使用replaceWithSourceString,個(gè)人覺(jué)得這個(gè)API很好用。
path.get("object").replaceWithSourceString("this.data")插入操作
??插入是樹(shù)操作的一種常見(jiàn)操作。子節(jié)點(diǎn)是個(gè)Array,前、中、后各種位置都可以插入新節(jié)點(diǎn)。下面來(lái)介紹下pushContainer、unshiftContainer、insertBefore、insertAfter操作。
??這里以給obj對(duì)象新增一個(gè)屬性myprop: "hello my property"為例:
const code = ` const obj = { count: 0, message: "hello world" } ` const ast = babylon.parse(code) const property = t.objectProperty( t.identifier("myprop"), t.stringLiteral("hello my property") )pushContainer 父節(jié)點(diǎn)的操作
??父節(jié)點(diǎn)為子節(jié)點(diǎn)Array插入一個(gè)node
traverse(ast, { ObjectExpression(path) { path.pushContainer("properties", property) } })insertAfter 兄弟節(jié)點(diǎn)的操作
??insertAfter也可以完成上述操作,需要找到message屬性,然后在后面插入node就搞定啦
traverse(ast, { ObjectProperty(path) { if ( t.isIdentifier(path.node.key, { name: "message" }) ) { path.insertAfter(property) } } })
??unshiftContainer和insertBefore與上面兩個(gè)相對(duì)應(yīng),這里不再舉例了,大家可以自己試一試。
??因?yàn)?b>properties是個(gè)數(shù)組,因此,我們可以直接使用數(shù)組操作
traverse(ast, { ObjectExpression(path) { // path.pushContainer("properties", property) path.node.properties.push(property) } })Remove 自我毀滅
??Remove方法極為簡(jiǎn)單,找到要?jiǎng)h除的NodePath,執(zhí)行Remove就結(jié)束了。如上述代碼,我們要?jiǎng)h除message屬性,代碼如下:
traverse(ast, { ObjectProperty(path) { if ( t.isIdentifier(path.node.key, { name: "message" }) ) { path.remove() } } })
到目前為止,AST的CURD我們都介紹完了,下面一篇文章以vue轉(zhuǎn)小程序為例,我們來(lái)實(shí)戰(zhàn)一波。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/107868.html
摘要:針對(duì)語(yǔ)法樹(shù)節(jié)點(diǎn)的查詢操作通常伴隨著和這兩種方法見(jiàn)下一篇文章。注意上述代碼打印出的和中的并不完全一致。如函數(shù),在中的為,但其實(shí)際的為。這個(gè)大家一定要注意哦,因?yàn)樵谖覀兒竺娴膶?shí)際代碼中也有用到。 ??在上一篇文章中,我們介紹了AST的Create。在這篇文章中,我們接著來(lái)介紹AST的Retrieve。??針對(duì)語(yǔ)法樹(shù)節(jié)點(diǎn)的查詢(Retrieve)操作通常伴隨著Update和Remove(這兩...
摘要:生成屬性這一步,我們要先提取原函數(shù)中的的對(duì)象。所以這里我們還是主要使用來(lái)訪問(wèn)節(jié)點(diǎn)獲取第一級(jí)的,也就是函數(shù)體將合并的寫(xiě)法用生成生成生成插入到原函數(shù)下方刪除原函數(shù)程序輸出將中的屬性提升一級(jí)這里遍歷中的屬性沒(méi)有再采用,因?yàn)檫@里結(jié)構(gòu)是固定的。 ??經(jīng)過(guò)之前的三篇文章介紹,AST的CRUD都已經(jīng)完成。下面主要通過(guò)vue轉(zhuǎn)小程序過(guò)程中需要用到的部分關(guān)鍵技術(shù)來(lái)實(shí)戰(zhàn)。 下面的例子的核心代碼依然是最簡(jiǎn)單...
摘要:思路可以實(shí)現(xiàn)時(shí)間復(fù)雜度的和,但是要求也是,只用是不可以的。但是在里面查找的時(shí)間復(fù)雜度依然是,可以想到用來(lái)記錄對(duì)應(yīng)的,這樣查找的時(shí)間也是常數(shù)。用可以保持順序,但是的時(shí)間復(fù)雜度是。 380. Insert Delete GetRandom O(1) Design a data structure that supports all following operations in aver...
吃豆人和削蘋(píng)果這兩個(gè)游戲想必大家都知道吧,本文運(yùn)用Python里的Pygame控制模塊編寫(xiě)出一個(gè)融合吃豆人+切水果的新手游:玩命吃蘋(píng)果,有興趣的話可以認(rèn)識(shí)一下 引言 哈哈哈!木木子今天浮現(xiàn)——早已來(lái)給大家看了不少具體內(nèi)容啦~ 涉及到的人工智能、新手、網(wǎng)絡(luò)爬蟲(chóng)、數(shù)據(jù)統(tǒng)計(jì)分析(這一塊的通常但是審批)手機(jī)游戲... PS: 吃豆人我寫(xiě)過(guò)了哈 Python+Pygame實(shí)戰(zhàn)之吃豆豆游戲的實(shí)...
摘要:首先要做到是,能想到的數(shù)據(jù)結(jié)構(gòu)只有兩三種,一個(gè)是,一個(gè)是,是,還有一個(gè),是。不太可能,因?yàn)殚L(zhǎng)度要而且不可變,題目也沒(méi)說(shuō)長(zhǎng)度固定??梢宰龅胶投际?。因?yàn)檫€有函數(shù),要可以,所以還需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)記錄順序,自然想到。 LRU Cache 題目鏈接:https://leetcode.com/problems... 這個(gè)題要求O(1)的復(fù)雜度。首先要做到get(key)是O(1),能想到的數(shù)據(jù)結(jié)...
閱讀 1855·2021-11-11 16:55
閱讀 2654·2021-08-27 13:11
閱讀 3693·2019-08-30 15:53
閱讀 2361·2019-08-30 15:44
閱讀 1479·2019-08-30 11:20
閱讀 1100·2019-08-30 10:55
閱讀 990·2019-08-29 18:40
閱讀 3113·2019-08-29 16:13