why 🔗
需要构建一个 javascript 的通用 AST 格式。
what 🔗
AST 节点类型 🔗
| 特性 |
Acorn 的设计意图 |
| 兼容 ESTree |
可与 Babel/ESLint 共享 AST |
| 简洁统一结构 |
每个节点有 type/start/end/loc |
| 语义清晰 |
每种语法有独立节点类型 |
| 插件可扩展 |
JSX、TS 插件可增加自定义节点 |
基础结构类节点 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
const x = 1; |
Program |
body: [ ...statements ] |
整个文件的根节点 |
const x = 1; |
VariableDeclaration |
kind: "const", declarations |
声明语句 |
x = 1 |
ExpressionStatement |
expression |
普通表达式语句 |
标识符与字面量 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
x |
Identifier |
name: "x" |
标识符(变量名) |
"hello" |
Literal |
value: "hello", raw: "\"hello\"" |
字面量(字符串、数字、布尔、null) |
42 |
Literal |
value: 42, raw: "42" |
数字字面量 |
表达式类节点 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
x + y |
BinaryExpression |
operator: "+", left, right |
二元表达式 |
-x |
UnaryExpression |
operator: "-", argument |
一元表达式 |
x++ |
UpdateExpression |
operator: "++", argument, prefix: false |
自增/自减 |
a && b |
LogicalExpression |
operator: "&&" |
逻辑表达式 |
obj.prop |
MemberExpression |
object, property, computed: false |
成员访问 |
obj["x"] |
MemberExpression |
computed: true |
方括号访问 |
foo() |
CallExpression |
callee, arguments |
函数调用 |
new Foo() |
NewExpression |
callee, arguments |
构造函数调用 |
(x > 0 ? 1 : 2) |
ConditionalExpression |
test, consequent, alternate |
三元运算符 |
() => x + 1 |
ArrowFunctionExpression |
params, body, expression |
箭头函数 |
语句类节点 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
if (x) {} |
IfStatement |
test, consequent, alternate |
if 语句 |
for (let i = 0; i < 3; i++) {} |
ForStatement |
init, test, update, body |
普通 for |
while (x < 10) |
WhileStatement |
test, body |
while 循环 |
do { ... } while(x) |
DoWhileStatement |
同上 |
do-while 循环 |
switch(x){} |
SwitchStatement |
discriminant, cases |
switch |
return x; |
ReturnStatement |
argument |
return |
break; |
BreakStatement |
无 |
break |
continue; |
ContinueStatement |
无 |
continue |
throw err; |
ThrowStatement |
argument |
throw |
try { ... } catch(e) {} |
TryStatement |
block, handler, finalizer |
try-catch-finally |
声明类节点 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
function foo(a) {} |
FunctionDeclaration |
id, params, body |
函数声明 |
const fn = function() {} |
FunctionExpression |
类似上面,但无 id |
函数表达式 |
class A {} |
ClassDeclaration |
id, superClass, body |
类声明 |
class A extends B {} |
同上 |
superClass 指向 B |
|
import x from "mod"; |
ImportDeclaration |
specifiers, source |
ES 模块导入 |
export default x; |
ExportDefaultDeclaration |
declaration |
默认导出 |
export { a, b }; |
ExportNamedDeclaration |
specifiers |
命名导出 |
对象、数组、模板字面量 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
{ a: 1, b: 2 } |
ObjectExpression |
properties |
对象字面量 |
[1, 2, 3] |
ArrayExpression |
elements |
数组字面量 |
`Hi ${name}` |
TemplateLiteral |
quasis, expressions |
模板字符串 |
模块与导入导出 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
import fs from 'fs' |
ImportDeclaration |
source, specifiers |
导入声明 |
export default foo; |
ExportDefaultDeclaration |
declaration |
默认导出 |
export { bar }; |
ExportNamedDeclaration |
specifiers |
命名导出 |
特殊结构 🔗
| JS 代码 |
AST 节点类型 |
关键属性 |
说明 |
(function(){})() |
CallExpression + FunctionExpression |
IIFE 调用 |
|
this |
ThisExpression |
无 |
this 关键字 |
super() |
Super |
无 |
调用父类构造 |
new.target |
MetaProperty |
meta, property |
元属性访问 |
how 🔗
scanner 🔗
parser 🔗
how to connect together 🔗
next works 🔗
v8 的解释器, Ignition将AST编译为字节码。 Turbofan 优化字节码。
references 🔗