成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

沒有AST, IDE中的錯誤提示、自動補全、重構、語法檢查......都玩不轉了

開發 開發工具
如果能把JavaScript源碼轉化成結構化的對象,就可以精確地知道一段代碼中有哪些變量名,函數名,參數...... 這樣就可以寫程序就可以進行處理了。

[[257628]]

 張大胖一上班,領導就扔了一個任務給他,把項目中的JavaScript代碼做點“小小”的改變:

1. 把 == 改為全等 ===

2. 把parsetInt不標準的調用改為標準用法 parseInt(xxx)-> parseInt(xxx,10)

對不熟悉JS的同學稍微解釋一下:

JS在比較兩個變量的時候,雙等號將執行類型轉換; 三等號將進行相同的比較,而不進行類型轉換 (如果類型不同, 只是總會返回 false );

parseInt(a,10) 表示以十進制的方式來解析。

對于這些任務,張大胖腦海中馬上閃現出了解決辦法:字符串替換。

對***個任務: 找到'==',替換成'==='就行 。

對第二個任務: parseInt(xxx) 改成parseInt(xxx,10), 沒法直接替換,得寫個正則表達式,找到那些只有一個參數的parseInt字符串,然后加上一個新的參數:10 。

張大胖對自己的正則表達式能力不太自信,如果考慮得不周全,代碼就可能被改壞了。

有沒有別的辦法?

01抽象語法樹

使用正則表達式,只能把JavaScript源代碼當做文本來處理,能力很弱,無法觸及到JavaScript的語法層面,正則表達式沒法知道這個地方是變量,那個地方是函數名.....

如果能把JavaScript源碼轉化成結構化的對象,就可以精確地知道一段代碼中有哪些變量名,函數名,參數...... 這樣就可以寫程序就可以進行處理了。

張大胖想起來自己沒有考及格的《編譯原理》,里邊講到了抽象語法樹(AST)不就是所謂結構化的東西嗎?

比如表達式 result = 6+7*3 , 用抽象語法樹來表示就是:

 

如果把所有的JavaScript代碼都轉化成這樣一顆AST的樹,那代碼的一切都盡在掌握, 可以任意修改了。


 

但是這其中有三個問題:

1. 怎么從文本形式的源代碼形成這么一個AST ?

讓自己寫程序實現那就太難了,得做詞法分析,語法分析等等。

2. 如何遍歷這個AST,來修改這顆樹的枝枝葉葉?

比如我想在AST這棵樹中添加一個新的節點,該怎么做?

3. 修改完成以后,怎么再次把AST變成文本的源代碼?

張大胖趕緊打開Google 搜索,很快便找到了三個開源的工具,正好完成對應的三個功能:

esprima : 從JavaScript源代碼形成AST

estraverse:遍歷樹的節點并修改

escodegen : 把修改完的AST再次轉化為源代碼。

02創建AST

說干就干,張大胖準備了一段代碼來做實驗:

  1. //源碼 
  2. function fun1(opt) { 
  3.     if (opt.status == 1) { 
  4.         console.log('1'); 
  5.     } 
  6.     if (opt.status == 2) { 
  7.         console.log('2'); 
  8.     } 
  9. function fun2(age) { 
  10.     if (parseInt(age) >= 18) { 
  11.         console.log('ok 你已經成年'); 
  12.     } 

使用esprima,輕輕松松就把它轉化成了抽象語法樹。

  1. //JS語法樹模塊 
  2. const esprima = require('esprima'); 
  3. //創建AST 
  4. const AST = esprima.parseScript(jsCode); 

(由于轉成樹后結構非常大,這里不再展示了, 感興趣的同學自己可以到http://esprima.org/demo/parse.html 去玩一把, 很有趣。 )

比如: if (parseInt(age) >= 18) 這一句,就被轉化成了這樣:

 

03遍歷修改AST

有了AST,就可以就是遍歷和修改了,還是使用開源的工具。

  1. //JS語法樹遍歷各節點 
  2. const estraverse = require('estraverse'); 
  3. //從JS語法樹生成源代碼 
  4. const escodegen = require('escodegen'); 
  5.  
  6. function walkIn(ast){ 
  7.     estraverse.traverse(ast, { 
  8.         enter: (node) => { 
  9.             toEqual(node);//把 == 改為全等 === 
  10.             setParseInt(node); //parseInt(a)-> parseInt(a,10) 
  11.         } 
  12.     }); 

這個函數負責把‘==’改成‘===’

  1. function toEqual(node) { 
  2.     if (node.operator === '==') { 
  3.         node.operator = '==='
  4.     } 

這個函數負責把parseInt改成標準調用:

  1. function setParseInt(node) { 
  2.     //判斷節點類型 方法名稱,方法的參數的數量,數量為1就增加第二個參數。 
  3.     if (node.type === 'CallExpression' && node.callee.name === 'parseInt' && node.arguments.length===1){ 
  4.         node.arguments.push({//增加參數,其實就是數組操作 
  5.             "type""Literal"
  6.             "value": 10, 
  7.             "raw""10" 
  8.         }); 
  9.     } 

經過這個函數,原來的 if (parseInt(age) >= 18) 就變成了下圖這樣,相當于增加了一個節點,對應的代碼就是 :if (parseInt(age,10) >= 18)

 

***使用escodegen 把修改過的AST再次變成源代碼,就大功告成了:

  1. //生成目標代碼 
  2. const code = escodegen.generate(ast); 
  3. //寫入文件..... 
  4. //....你懂的 

通過這個實驗,張大胖基本上了解了AST的原理和用法,接下來可以著手正式的編程了。

04總結

本文的例子用AST也許不是***解, 主要是為了展示AST的處理技術, AST實際上就是源代碼的一種結構化表示, 利用它及相關工具可以方便地優化和修改代碼,只要是你能對這棵“AST樹”做“修剪”就可以對源代碼做各種“手腳”:

JavaScript代碼語法、風格的檢查

在IDE中的錯誤提示、自動補全,重構

代碼的壓縮和混淆 代碼的轉換 ......

有這么強大的功能,AST處理技術是很多知名工具的基礎, 例如babel,webpack,還有jd taro等都把AST用得***。

【本文為51CTO專欄作者“劉欣”的原創稿件,轉載請通過作者微信公眾號coderising獲取授權】

 

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO
相關推薦

2012-12-24 09:54:06

大數據數據科學家

2013-01-10 12:50:38

移動游戲人才

2020-11-20 11:02:26

AST函數Javascript

2009-12-09 10:46:06

PHP檢查語法錯誤

2022-01-18 18:46:55

Eslint抽象語法樹Babel

2009-07-17 14:55:38

ibatis官方

2014-05-15 11:02:34

Linux操作系統國產操作系統

2021-09-14 11:10:20

程序員技能開發者

2009-06-03 17:00:08

Eclipse自動補全

2017-07-04 15:07:44

Windows 7Windows數據錯誤

2020-12-08 06:20:49

前端重構Vue

2020-07-31 07:44:12

代碼自動補全

2022-12-26 00:02:24

重構代碼軟件

2024-05-10 08:51:31

Python命令補全工具

2017-06-05 14:27:56

MyCLIMySQLMariaDB

2022-01-13 14:06:37

Python 開發編程語言

2024-11-11 00:38:13

Mypy靜態類型

2014-12-31 17:12:54

模糊查詢模糊查詢

2011-04-20 08:55:17

BlackBerry

2016-12-20 09:30:22

shell腳本linux
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜电影网 | 99国产精品一区二区三区 | 牛牛热在线视频 | 午夜免费福利电影 | 天天色图 | 欧美一区二区三区在线观看 | 国产一区二区精品在线 | 欧美日韩国产综合在线 | 99国内精品久久久久久久 | 国产精品日日摸夜夜添夜夜av | 中文字幕在线观看www | 国产精品国产精品国产专区不卡 | 在线观看中文字幕 | 国产在线小视频 | 精品国产乱码久久久久久88av | 国产日韩欧美激情 | 天天躁日日躁aaaa视频 | 亚洲国产精品网站 | 国产1区在线 | 黄色毛片在线看 | 欧美日韩专区 | 91秦先生艺校小琴 | 免费观看一区二区三区毛片 | 日韩一级在线 | 在线视频一区二区三区 | 成人免费视频网站在线看 | h免费观看 | 国产精品一区二区在线免费观看 | 中文在线一区二区 | 国产精品99久久久精品免费观看 | 视频三区| 亚洲精品二三区 | 国产一区久久久 | 刘亦菲国产毛片bd | 最近免费日本视频在线 | 久久免费观看一级毛片 | 日韩中文字幕视频在线观看 | 中文在线a在线 | 一区二区三区四区不卡视频 | 欧美精品一区二区三区在线播放 | 成人av一区 |