中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用抽象語法樹AST實現一個AOP切面邏輯

發布時間:2023-04-07 10:20:04 來源:億速云 閱讀:132 作者:iii 欄目:開發技術

這篇文章主要介紹了怎么使用抽象語法樹AST實現一個AOP切面邏輯的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇怎么使用抽象語法樹AST實現一個AOP切面邏輯文章都會有所收獲,下面我們一起來看看吧。

一、實現目的

js 文件下的全部方法添加一個開始事件和一個結束事件并傳入方法名,以便監聽某個方法的調用。

1、work.js

function eat(){
    let food = "apple"
    let time = '2小時'
    return '吃' + food + '用時' + time
}
function work(){
}
console.log(eat())

控制臺打印

怎么使用抽象語法樹AST實現一個AOP切面邏輯

可以看到,輸入了執行 eat 方法的開始事件及結束事件。其實,這個過程就是 work.js 轉成語法樹后,對方法節點進行了處理,添加了兩個切面方法:startend 事件。

2、aop.js

這個文件用來聲明 startend 事件。

function start(funcName){
    console.log('開始執行:' + funcName + '方法')
}
function end(funcName){
    console.log('執行結束:' + funcName + '方法')
}

二、利用語法樹添加切面事件

//文件操作工具
const fs = require('fs');
//JS代碼轉語法樹工具
const parser = require('./babel-core/node_modules/babylon');
//語法樹遍歷工具
const traverse = require('./babel-core/node_modules/babel-traverse');
//語法樹轉JS代碼工具
const generator = require('./babel-core/node_modules/babel-generator');
//聲明語法樹類型工具
const t = require('./babel-core/node_modules/babel-types');
//獲取aop代碼
let aop = fs.readFileSync('./aop.js','utf-8')
//獲取需要添加切面的代碼
let content = fs.readFileSync('./work.js','utf-8')
//將需要添加切面的代碼轉換為語法樹
let ast = parser.parse(content,{
    sourceType:'script'
})
//遍歷指定語法樹時操作項(這里遍歷的指定節點是FunctionDeclaration方法)
const visitor = {
    FunctionDeclaration:({ node }) => {
        //獲取每個方法體里面的節點
        let funcBody = node.body.body
        //創建一個名為start,參數為當前方法名的執行節點,后面的參數為創建一個名為start方法的參數
        let start = t.callExpression(t.identifier('start'), [t.identifier(`"${node.id.name}"`)])
        //添加到方法的最前面
        funcBody.unshift(start)
        //判斷最后一個節點是不是return,方式結束事件調用節點在最后無法調用。
        let lastNode = funcBody.slice(-1)
        //創建一個名為end,參數為當前方法名的執行節點,后面的參數為end方法的參數
        let end = t.callExpression(t.identifier('end'), [t.identifier(`"${node.id.name}"`)])
        //設定end節點添加的位置
        let insertEndEventPosition = (funcBody.length)
        if(lastNode[0].type == 'ReturnStatement'){
            //放在return節點的前面
            insertEndEventPosition -= 1
        }
        //添加end節點
        funcBody.splice(insertEndEventPosition,0,end)
    }
}
//開始遍歷操作語法樹
traverse.default(ast,visitor)
//將處理完的語法樹再次轉換為JS代碼
let codeResult = generator.default(ast)
//這里需要添加aop里面的兩個切面事件到最終的JS代碼里。
let outFileCode = aop + '\n\n' + codeResult.code
// 寫入文件操作
fs.mkdir('cache',(err)=>{
    if(!err){
        fs.writeFile('cache/main.js',outFileCode,(err)=>{
            if(!err){
                console.log('文件創建完成')
            }
        })
    }
})

上面的代碼執行完后,看下 main.js 生成的代碼內容。

function start(funcName){
    console.log('開始執行:' + funcName + '方法')
}
function end(funcName){
    console.log('執行結束:' + funcName + '方法')
}
function eat() {
    start("eat")
    let food = "apple";
    let time = '2小時';
    end("eat")
    return '吃' + food + '用時' + time;
}
function work() {
    start("work")
    end("work")
}
console.log(eat());

相比較之前的 work.js 文件,添加了兩個切面方法的同時,保證每個方法都添加了 startend 事件。這樣再調用的時候便可直接在執行前后操作其他任務了。

關于“怎么使用抽象語法樹AST實現一個AOP切面邏輯”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“怎么使用抽象語法樹AST實現一個AOP切面邏輯”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

含山县| 桐乡市| 普宁市| 信丰县| 蒲城县| 岱山县| 互助| 什邡市| 安乡县| 怀仁县| 富顺县| 金坛市| 陕西省| 诏安县| 宜宾市| 汉阴县| 乌海市| 汤原县| 禹州市| 崇左市| 怀化市| 兴业县| 苗栗县| 崇义县| 霍林郭勒市| 交口县| 兰州市| 三河市| 清水县| 临澧县| 广灵县| 岚皋县| 尼玛县| 滨州市| 沂南县| 江达县| 镇雄县| 昭通市| 西峡县| 赤水市| 光山县|