前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【编译技术】:解读 Babel AST Format——01

【编译技术】:解读 Babel AST Format——01

作者头像
WEBJ2EE
发布2020-10-26 15:09:31
6740
发布2020-10-26 15:09:31
举报
文章被收录于专栏:WebJ2EEWebJ2EE
代码语言:javascript
复制
目录
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\@babel\parser\bin\babel-parser.js)

代码语言:javascript
复制
#!/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.
代码语言:javascript
复制
export interface Program extends BaseNode {
  type: "Program";
  body: Array<Statement>;
  directives: Array<Directive>;
  sourceType: "script" | "module";
  interpreter: InterpreterDirective | null;
  sourceFile: string;
}
代码语言:javascript
复制
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.

代码示例:

代码语言:javascript
复制
'use strict';

AST Node:

代码语言:javascript
复制
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.

代码示例:

代码语言:javascript
复制
@isTestable(true)
class MyClass { }
function isTestable(value) {}

AST Node:

代码语言:javascript
复制
export interface Decorator extends BaseNode {
  type: "Decorator";
  expression: Expression;
}

4. 示例

代码示例:

代码语言:javascript
复制
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:

代码语言:javascript
复制
{
  "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


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档