目录
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?
本期涉及:
注1:Misc 是 Miscellaneous 的缩写,代表杂项。
3. 语法规范回顾
3.1. InterpreterDirective 是什么?
示例:
#!:
代码示例:(node_modules\@babel\parser\bin\babel-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:
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 是什么?
代码示例:
'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