【编译技术】:解读 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
- 怎么采集dedecms自定义内容模型
- dedecms怎样调用指定id文章?
- c++ list, vector, map, set 区别与用法比较
- 前台开发从头说起:谈谈CSS选择符
- dedecms无法登录提示本页面禁止返回
- 前台开发从头说起:理解css盒模型
- 两个js冲突怎么解决?试试这四个方法
- dedecms如何去除后台登陆验证码
- DEDECMS自定义表单unix时间戳转换成常规时间方法及增加表单添加时间方法
- dedecms自定义表单发布成功后返回当前页面
- 前端构建工具 Gulp.js 上手实例
- dedecms数据库内容替换安全确认码不显示怎么解决
- 利用宏避免发送确认邮件时忘记添加附件
- dateDiff在Objective-C中的实现
- 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 数组属性和方法
- 虚拟机安装Linux rhel7.3操作系统(具体步骤)
- linux系统安装zookeeper 服务的方法
- 详解Linux中关于引号的那些事
- seaborn可视化数据框中的多个列元素
- Android OpenGLES如何给相机添加滤镜详解
- VmWare安装centos7无法上网的解决方法
- 如何修改CentOS服务器时间为北京时间
- linux下搭建go环境的安装配置讲解
- linux下搭建scala环境并写个简单的scala程序
- 在Linux系统下上传项目到码云的方法
- 使用seaborn绘制热图
- CentOS中环境变量与配置文件的深入讲解
- 详解linux下fsevents模块引起的npm ls报错解决办法
- 解决nginx/apache静态资源跨域访问问题详解
- 可怕的万圣节 Linux 命令