【AST 基础】二、AST 的 types 组件

types 组件

types 能用于节点类型的判断节点的生成,但是主要还是用来节点的生成,因为节点类型的判断可以不用该组件,也能实现

类型判断

// 其他类型也是一样
type.isIdentifier(path.node) // 相当于 path.node.type === 'Identifier'
type.isIdentifier(path.node,{'name':'x'}) // 相当于 path.node.type === 'Identifier' && path.node.name === 'x'

节点生成

生成 实例代码

const fs = require('fs')
const type = require("@babel/types")
const generator = require("@babel/generator").default // AST 转换为 代码

let objPro1 = type.objectProperty( 
    key = type.identifier(name = "name"),  // 第一个属性
    value = type.stringLiteral(value = "haha")) // 第一个属性值
let bojPro2 = type.objectProperty(
    key = type.identifier(name = "add"),
    value = type.functionExpression( // 函数节点
        id = null,
        params = [type.identifier(name = "a"), type.identifier(name = "b")], // 参数列表
        body = type.blockStatement( // 函数体
            body = [type.returnStatement( // 返回值
                argument = type.binaryExpression( // 二项式
                    operator = "+",
                    left = type.binaryExpression(
                        operator = "+",
                        left = type.identifier(name = "a"),
                        right = type.identifier(name = "b")),
                    right = type.numericLiteral(value = 1000))
            )]
        )))
let bojPro3 = type.objectProperty(
    key = type.identifier(name = "mul"), // 第三个属性
    value = type.functionExpression( // 第三个属性值
        id = null,
        params = [type.identifier(name = "a"), type.identifier(name = "b")],
        body = type.blockStatement(
            body = [type.returnStatement(
                argument = type.binaryExpression(
                    operator = "+",
                    left = type.binaryExpression(
                        operator = "*",
                        left = type.identifier(name = "a"),
                        right = type.identifier(name = "b")),
                    right = type.numericLiteral(value = 1000))
            )]
        )))
let obj = type.objectExpression([objPro1, bojPro2, bojPro3]) // 变量初始化
let letDec = type.variableDeclarator(type.identifier(name = "obj"), init = obj) // 变量名 
let localAst = type.variableDeclaration("let", [letDec])  // 声明变量

// ast 转化为 代码
let code = generator(localAst).code
fs.writeFile("./output/code.js", code, (err => {
}))

上面 使用到 stringLiteral 、numericLiteral types 还提供了其他字面量,按照语法树来,都是差不多的

declare function stringLiteral(value: string): StringLiteral;
declare function numericLiteral(value: number): NumericLiteral;
declare function nullLiteral(): NullLiteral;
declare function booleanLiteral(value: boolean): BooleanLiteral;
declare function regExpLiteral(pattern: string, flags?: string): RegExpLiteral;

当界面量太多,太复杂的时候,Bable 也提供了一个简便的方式 valueToNode()

// 可以看出 valueToNode 可以很方便的生成其他类型
export function valueToNode(value: undefined): Identifier
export function valueToNode(value: boolean): BooleanLiteral
export function valueToNode(value: null): NullLiteral
export function valueToNode(value: string): StringLiteral
export function valueToNode(value: number): NumericLiteral | BinaryExpression | UnaryExpression
export function valueToNode(value: RegExp): RegExpLiteral
export function valueToNode(value: ReadonlyArray<undefined | boolean | null | string | number | RegExp | object>): ArrayExpression
export function valueToNode(value: object): ObjectExpression
export function valueToNode(value: undefined | boolean | null | string | number | RegExp | object): Expression
console.log(generator(type.valueToNode(123)).code)
console.log(generator(type.valueToNode('mimi')).code)
console.log(generator(type.valueToNode(undefined)).code)
console.log(generator(type.valueToNode(null)).code)
/*
123
"mimi"   
undefined
null  
 */
发表评论 / Comment

用心评论~