【编译技术】:解读 Babel AST Format——01
目录
1. 什么是 Babel AST Format?
2. 本期涉及哪些 AST node types?
3. 语法规范回顾
3.1. InterpreterDirective 是什么?
3.2. Directive 是什么?
3.3. Decorator 是什么?
4. 示例
1. 什么是 Babel AST Format?
The Babel parser generates AST according to Babel AST format. It is based on ESTree spec with some deviations.
2. 本期涉及哪些 AST node types?
本期涉及:
- Misc
- Decorator
- Directive
- DirectiveLiteral
- InterpreterDirective
注1:Misc 是 Miscellaneous 的缩写,代表杂项。
3. 语法规范回顾
3.1. InterpreterDirective 是什么?
示例:
#!:
- #! 叫做“Shebang”或者“Sha-bang”。
- Shebang 的名字来自于 SHArp 和 bang,或haSH bang的缩写,指代Shebang中#!两个符号的典型Unix名称。Unix术语中,井号通常称为sharp,hash或mesh;而叹号则常常称为bang。
- Shebang通常出现在类Unix系统的脚本中第一行,作为前两个字符。
代码示例:(node_modules@babelparserbinbabel-parser.js)
#!/usr/bin/env node
/* eslint no-var: 0 */
var parser = require("..");
var fs = require("fs");
var filename = process.argv[2];
if (!filename) {
console.error("no filename specified");
} else {
var file = fs.readFileSync(filename, "utf8");
var ast = parser.parse(file);
console.log(JSON.stringify(ast, null, " "));
}
AST Node:
- Babylon already parses "shebangs" (#!env node) but put's in a comment in the Program node. Now we are just creating an actual node for it.
- Add a new interpreter field to the Program node.
export interface Program extends BaseNode {
type: "Program";
body: Array<Statement>;
directives: Array<Directive>;
sourceType: "script" | "module";
interpreter: InterpreterDirective | null;
sourceFile: string;
}
export interface InterpreterDirective extends BaseNode {
type: "InterpreterDirective";
value: string;
}
3.2. Directive 是什么?
- A Directive Prologue is the longest sequence of ExpressionStatement productions occurring as the initial StatementListItem or ModuleItem productions of a FunctionBody, a ScriptBody, or a ModuleBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed by a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence.
- A Use Strict Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either the exact code unit sequences "use strict" or 'use strict'. A Use Strict Directive may not contain an EscapeSequence or LineContinuation.
代码示例:
'use strict';
AST Node:
export interface Directive extends BaseNode {
type: "Directive";
value: DirectiveLiteral;
}
export interface DirectiveLiteral extends BaseNode {
type: "DirectiveLiteral";
value: string;
}
3.3. Decorator 是什么?
Decorators @decorator are functions called on class elements or other JavaScript syntax forms during definition, potentially wrapping or replacing them with a new value returned by the decorator.
代码示例:
@isTestable(true)
class MyClass { }
function isTestable(value) {}
AST Node:
export interface Decorator extends BaseNode {
type: "Decorator";
expression: Expression;
}
4. 示例
代码示例:
const parser = require("@babel/parser");
const code = `
'use strict';
@testable()
class MyApp{}
function testable() {}
`;
const node = parser.parse(code, {plugins: ["decorators-legacy"]});
console.log(JSON.stringify(node));
AST Nodes:
{
"type": "File",
"start": 0,
"end": 64,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 6,
"column": 0
}
},
"errors": [],
"program": {
"type": "Program",
"start": 0,
"end": 64,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 6,
"column": 0
}
},
"sourceType": "script",
"interpreter": null,
"body": [{
"type": "ClassDeclaration",
"start": 15,
"end": 40,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 4,
"column": 13
}
},
"decorators": [{
"type": "Decorator",
"start": 15,
"end": 26,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 11
}
},
"expression": {
"type": "CallExpression",
"start": 16,
"end": 26,
"loc": {
"start": {
"line": 3,
"column": 1
},
"end": {
"line": 3,
"column": 11
}
},
"callee": {
"type": "Identifier",
"start": 16,
"end": 24,
"loc": {
"start": {
"line": 3,
"column": 1
},
"end": {
"line": 3,
"column": 9
},
"identifierName": "testable"
},
"name": "testable"
},
"arguments": []
}
}],
"id": {
"type": "Identifier",
"start": 33,
"end": 38,
"loc": {
"start": {
"line": 4,
"column": 6
},
"end": {
"line": 4,
"column": 11
},
"identifierName": "MyApp"
},
"name": "MyApp"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 38,
"end": 40,
"loc": {
"start": {
"line": 4,
"column": 11
},
"end": {
"line": 4,
"column": 13
}
},
"body": []
}
}, {
"type": "FunctionDeclaration",
"start": 41,
"end": 63,
"loc": {
"start": {
"line": 5,
"column": 0
},
"end": {
"line": 5,
"column": 22
}
},
"id": {
"type": "Identifier",
"start": 50,
"end": 58,
"loc": {
"start": {
"line": 5,
"column": 9
},
"end": {
"line": 5,
"column": 17
},
"identifierName": "testable"
},
"name": "testable"
},
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 61,
"end": 63,
"loc": {
"start": {
"line": 5,
"column": 20
},
"end": {
"line": 5,
"column": 22
}
},
"body": [],
"directives": []
}
}],
"directives": [{
"type": "Directive",
"start": 1,
"end": 14,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 13
}
},
"value": {
"type": "DirectiveLiteral",
"start": 1,
"end": 13,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 12
}
},
"value": "use strict",
"extra": {
"raw": "'use strict'",
"rawValue": "use strict"
}
}
}]
},
"comments": []
}
参考资料1:
Babel AST format: https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md ESTree spec: https://github.com/estree/estree ECMAScript® 2015 Language Specification: http://www.ecma-international.org/ecma-262/6.0/index.html
参考资料2:Directive
Add InterpreterDirective Node: https://babeljs.io/docs/en/v7-migration-api#add-interpreterdirective-node-7928httpsgithubcombabelbabelpull7928 Directive Prologues and the Use Strict Directive: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-directive-prologues-and-the-use-strict-directive
参考资料3:Decorator
https://babeljs.io/docs/en/babel-plugin-proposal-decorators https://github.com/tc39/proposal-decorators https://github.com/tc39/proposal-decorators/issues/69
- 用命令重启IIS 常重启IIS的朋友看过来
- Python基础01 Hello World!
- 剑指OFFER之从上往下打印二叉树(九度OJ1523)
- 给你的博客加上“Fork me on Github”彩带
- Android Studio添加PNG图片报错原因
- 剑指OFFER之包含min函数的栈(九度OJ1522)
- 使用VS2010开发Qt程序的一点经验
- 用Qt写软件系列五:一个安全防护软件的制作(3)
- 剑指OFFER之顺时针打印矩阵(九度OJ1391)
- 用Qt写软件系列五:一个安全防护软件的制作(2)
- 2018年值得关注的200场机器学习会议
- Linux开机启动(bootstrap)
- 剑指OFFER之树的子结构(九度OJ1520)
- 万物智联慧结成网:信息技术驱动物流产业转型升级
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ROS机器人URDF建模
- 这是我见过最牛逼的Shell,619行代码!
- 设计模式(五):利用原型模式复制几个葫芦娃
- Vue中数组变动监听
- which命令
- 如何将tensorflow1.x代码改写为pytorch代码(以图注意力网络(GAT)为例)
- tomcat设置好环境变量,依然无法通过cmd startup命令启动
- python调用百度图片识别api
- [Go]GO语言实战-开源WEB客服GO-FLY-gorm下分页的实现
- [Go]GO语言实战-小程序或公众号接口gin框架验证微信服务器消息签名-开源WEB客服
- php一步一步实现mysql协议(一)——抓包本地mysql通信
- [MySQL] 利用explain查看sql语句中使用的哪个索引
- php一步一步实现mysql协议(二) ——握手初始化
- php一步一步实现mysql协议(三) ——登录认证密码加密
- php一步一步实现mysql协议(四)——执行命令