AST (Abstract Syntax Tree(抽象语法树)) 是源代码语法结构的一种抽象表示。不了解 AST 的,可以看这篇文章。
创建 AST 节点是转换AST节点时的常见操作。本文用 @babel/types 来创建 AST节点。@babel/types 是根据 babel 的 AST 规范来创建 AST。规范说明见这里。
下面,我们来具体看代码。代码中的 t
为 require('@babel/types')
。完整代码见这里。
创建数字
代码语言:javascript复制t.numericLiteral(1)
输出:
代码语言:javascript复制1
创建字符串
代码语言:javascript复制t.stringLiteral('a str')
输出:
代码语言:javascript复制"a str"
创建布尔值
代码语言:javascript复制t.booleanLiteral(true)
t.booleanLiteral(false)
输出:
代码语言:javascript复制true
false
创建null
代码语言:javascript复制t.nullLiteral()
输出:
代码语言:javascript复制null
创建对象
代码语言:javascript复制const nameKey =
t.objectProperty(
t.identifier('name'),
t.stringLiteral('Joel')
)
const agetKey =
t.objectProperty(
t.identifier('age'),
t.numericLiteral(18)
)
t.objectExpression([nameKey, agetKey])
输出:
代码语言:javascript复制{
name: "Joel",
age: 18
}
创建获取对象的属性
代码语言:javascript复制t.memberExpression(
t.identifier('obj'),
t.identifier('name')
)
t.memberExpression(
t.identifier('obj'),
t.identifier('name'),
true
)
输出:
代码语言:javascript复制obj.name
obj[name]
创建数组
代码语言:javascript复制const item1 = t.numericLiteral(1)
const item2 = t.numericLiteral(2)
t.arrayExpression([item1, item2])
输出:
代码语言:javascript复制[1, 2]
创建获取数组的内容
代码语言:javascript复制t.memberExpression(
t.identifier('arr'),
t.numericLiteral(1),
true
)
输出:
代码语言:javascript复制arr[1]
创建二元表达式
代码语言:javascript复制t.binaryExpression(
' ', // 操作符。 还支持:==, ===, != 等
item1, // 左操作数
item2
)
输出:
代码语言:javascript复制1 2
创建三元表达式
代码语言:javascript复制t.conditionalExpression(
t.binaryExpression(
'>',
t.numericLiteral(4),
t.numericLiteral(3)
),
t.numericLiteral(4),
t.numericLiteral(3)
)
输出:
代码语言:javascript复制4 > 3 ? 4 : 3
创建逻辑表达式
代码语言:javascript复制t.logicalExpression(
'||',
t.identifier('num'),
t.numericLiteral(0)
)
t.logicalExpression(
'&&',
t.identifier('obj'),
t.memberExpression(
t.identifier('obj'),
t.identifier('name')
)
)
输出:
代码语言:javascript复制num || 0
obj && obj.name
创建条件语句if
代码语言:javascript复制t.binaryExpression(
'>',
t.numericLiteral(4),
t.numericLiteral(3)
),
t.blockStatement(
[
t.expressionStatement(
t.callExpression(
t.memberExpression(
t.identifier('console'),
t.identifier('log')
),
[
t.booleanLiteral(true)
]
)
)
]
)
输出:
代码语言:javascript复制if (4 > 3) {
console.log(true);
}
不知到怎么创建 else if 和 else。
创建for循环
代码语言:javascript复制t.forStatement(
t.variableDeclaration(
'let',
[
t.variableDeclarator(
t.identifier('i'),
t.numericLiteral(0)
)
]
),
t.binaryExpression(
'<',
t.identifier('i'),
t.numericLiteral(3)
),
t.updateExpression(
' ',
t.identifier('i')
),
t.blockStatement([
t.emptyStatement()
])
)
输出:
代码语言:javascript复制for (let i = 0; i < 3; i ) {
;
}
创建变量定义
代码语言:javascript复制t.variableDeclaration(
'let', // 还支持 const 和 var
[
t.variableDeclarator(
t.identifier('b'), // 变量名
)
]
)
t.variableDeclaration(
'let', // 还支持 const 和 var
[
t.variableDeclarator(
t.identifier('b'), // 变量名
)
]
)
t.assignmentExpression(
'=',
t.identifier('b'),
t.numericLiteral(1)
)
输出:
代码语言:javascript复制let a = 1;
let b;
b = 1
创建定义函数
代码语言:javascript复制t.functionDeclaration(
t.identifier('add'), // 函数名
[t.identifier('a'), t.identifier('b')], // 参数
t.blockStatement([ // 函数体
t.variableDeclaration(// const sum = a b
'const',
[
t.variableDeclarator(
t.identifier('sum'), // 变量名
t.binaryExpression(' ', t.identifier('a'), t.identifier('b')) // a b
),
]
),
t.returnStatement(t.identifier('sum')) // return sum
])
)
输出:
代码语言:javascript复制function add(a, b) {
const sum = a b;
return sum;
}
创建箭头函数
代码语言:javascript复制const declarationArrowFun =
t.arrowFunctionExpression(
[t.identifier('a'), t.identifier('b')], // 参数
t.blockStatement([ // 函数体
t.variableDeclaration(// const sum = a b
'const',
[
t.variableDeclarator(
t.identifier('sum'), // 变量名
t.binaryExpression(' ', t.identifier('a'), t.identifier('b')) // a b
),
]
),
t.returnStatement(t.identifier('sum')) // return sum
])
)
t.variableDeclaration(
'let', // 还支持 const 和 var
[
t.variableDeclarator(
t.identifier('add2'), // 变量名
declarationArrowFun
)
]
)
输出:
代码语言:javascript复制function add(a, b) {
const sum = a b;
return sum;
}
let add2 = (a, b) => {
const sum = a b;
return sum;
};
创建函数调用
代码语言:javascript复制t.callExpression(
t.identifier('add'),
[
t.numericLiteral(1),
t.numericLiteral(2)
]
)
输出:
代码语言:javascript复制add(1, 2)