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

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

作者头像
WEBJ2EE
发布2020-11-05 10:39:04
1.4K1
发布2020-11-05 10:39:04
举报
文章被收录于专栏:WebJ2EEWebJ2EE
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?

本期涉及:

  • Expressions
    • Super
    • Import
    • ThisExpression
    • ArrowFunctionExpression
    • YieldExpression
    • AwaitExpression
    • ArrayExpression
    • ObjectExpression
      • ObjectMember
        • ObjectProperty
        • ObjectMethod
    • RecordExpression
    • TupleExpression
    • FunctionExpression
    • Unary operations
      • UnaryExpression
        • UnaryOperator
      • UpdateExpression
        • UpdateOperator
    • Binary operations
      • BinaryExpression
        • BinaryOperator
      • AssignmentExpression
        • AssignmentOperator
      • LogicalExpression
        • LogicalOperator
      • SpreadElement
      • ArgumentPlaceholder
      • MemberExpression
      • BindExpression
    • ConditionalExpression
    • CallExpression
    • NewExpression
    • SequenceExpression
    • ParenthesizedExpression
    • DoExpression

3. 示例

3.1. Super

AST:A super pseudo-expression.

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

示例:

代码语言:javascript
复制
class App extends React.Component{
    constructor(props){
        super(props);
    }
}

3.2. Import

AST:A import pseudo-expression.

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

示例:

代码语言:javascript
复制
import("lodop");

3.3. ThisExpression

AST:A this expression.

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

示例:

代码语言:javascript
复制
function Person(){
    this.xm = "John";
}

3.4. ArrowFunctionExpression

AST:A fat arrow function expression, e.g., let foo = (bar) => { /* body */ }.

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

示例:

代码语言:javascript
复制
() => {}

3.5. YieldExpression

AST:A yield expression.

代码语言:javascript
复制
export interface YieldExpression extends BaseNode {
  type: "YieldExpression";
  argument: Expression | null;
  delegate: boolean;
}

示例:

代码语言:javascript
复制
function* fn(){
    yield 3;
}

3.6. AwaitExpression

AST:A await expression.

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

示例:

代码语言:javascript
复制
async function fn(){
    await 3;
}

3.7. ArrayExpression

AST:An array expression..

代码语言:javascript
复制
export interface ArrayExpression extends BaseNode {
  type: "ArrayExpression";
  elements: Array<null | Expression | SpreadElement>;
}

示例:

代码语言:javascript
复制
[1, 2, 3]

3.8. ObjectExpression

AST:An object expression.

代码语言:javascript
复制
export interface ObjectExpression extends BaseNode {
  type: "ObjectExpression";
  properties: Array<ObjectMethod | ObjectProperty | SpreadElement>;
}

export interface ObjectMethod extends BaseNode {
  type: "ObjectMethod";
  kind: "method" | "get" | "set";
  key: Expression | Identifier | StringLiteral | NumericLiteral;
  params: Array<Identifier | Pattern | RestElement | TSParameterProperty>;
  body: BlockStatement;
  computed: boolean;
  generator: boolean;
  async: boolean;
  decorators: Array<Decorator> | null;
  returnType: TypeAnnotation | TSTypeAnnotation | Noop | null;
  typeParameters: TypeParameterDeclaration | TSTypeParameterDeclaration | Noop | null;
}

export interface ObjectProperty extends BaseNode {
  type: "ObjectProperty";
  key: Expression | Identifier | StringLiteral | NumericLiteral;
  value: Expression | PatternLike;
  computed: boolean;
  shorthand: boolean;
  decorators: Array<Decorator> | null;
}

export interface RestElement extends BaseNode {
  type: "RestElement";
  argument: LVal;
  decorators: Array<Decorator> | null;
  typeAnnotation: TypeAnnotation | TSTypeAnnotation | Noop | null;
}

示例:

代码语言:javascript
复制
({
    xm: "John",
    getXm(){
    },
    ...props,
})

3.9. RecordExpression

3.10. TupleExpression

proposal-record-tuple:

  • This proposal introduces two new deeply immutable data structures to JavaScript:
    • Record, a deeply immutable Object-like structure #{ x: 1, y: 2 }
    • Tuple, a deeply immutable Array-like structure #[1, 2, 3, 4]
  • Records and Tuples can only contain primitives and other Records and Tuples. You could think of Records and Tuples as "compound primitives". By being thoroughly based on primitives, not objects, Records and Tuples are deeply immutable.
  • Records and Tuples support comfortable idioms for construction, manipulation and use, similar to working with objects and Arrays. They are compared deeply by their contents, rather than by their identity.

AST:

代码语言:javascript
复制
export interface RecordExpression extends BaseNode {
  type: "RecordExpression";
  properties: Array<ObjectProperty | SpreadElement>;
}

export interface TupleExpression extends BaseNode {
  type: "TupleExpression";
  elements: Array<Expression | SpreadElement>;
}

3.11. FunctionExpression

AST:A function expression.

代码语言:javascript
复制
export interface FunctionExpression extends BaseNode {
  type: "FunctionExpression";
  id: Identifier | null;
  params: Array<Identifier | Pattern | RestElement | TSParameterProperty>;
  body: BlockStatement;
  generator: boolean;
  async: boolean;
  returnType: TypeAnnotation | TSTypeAnnotation | Noop | null;
  typeParameters: TypeParameterDeclaration | TSTypeParameterDeclaration | Noop | null;
}

示例:

代码语言:javascript
复制
const fn = function(){}

3.12. Unary operations——UnaryExpression

AST:A unary operator expression.

代码语言:javascript
复制
export interface UnaryExpression extends BaseNode {
  type: "UnaryExpression";
  operator: "void" | "throw" | "delete" | "!" | "+" | "-" | "~" | "typeof";
  argument: Expression;
  prefix: boolean;
}

示例:

代码语言:javascript
复制
+3;

3.13. Unary operations——UpdateExpression

AST:An update (increment or decrement) operator expression.

代码语言:javascript
复制
export interface UpdateExpression extends BaseNode {
  type: "UpdateExpression";
  operator: "++" | "--";
  argument: Expression;
  prefix: boolean;
}

示例:

代码语言:javascript
复制
x++;

3.14. Binary operations——BinaryExpression

AST:A binary operator expression.

代码语言:javascript
复制
export interface BinaryExpression extends BaseNode {
  type: "BinaryExpression";
  operator: "+" | "-" | "/" | "%" | "*" | "**" | "&" | "|" | ">>" | ">>>" | "<<" | "^" | "==" | "===" | "!=" | "!==" | "in" | "instanceof" | ">" | "<" | ">=" | "<=";
  left: Expression | PrivateName;
  right: Expression;
}

示例:

代码语言:javascript
复制
x + y

3.15. Binary operations——AssignmentExpression

AST:An assignment operator expression. It has short-circuiting behaviour if the operator is one of "||=", "&&=", and "??=".

代码语言:javascript
复制
export interface AssignmentExpression extends BaseNode {
  type: "AssignmentExpression";
  operator: string;
  left: LVal;
  right: Expression;
}
enum AssignmentOperator {
  "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**="
    | "<<=" | ">>=" | ">>>="
    | "|=" | "^=" | "&="
    | "||=" | "&&=" | "??="
}

示例:

代码语言:javascript
复制
x += 2;

3.16. Binary operations——LogicalExpression

AST:A logical operator expression.

代码语言:javascript
复制
export interface LogicalExpression extends BaseNode {
  type: "LogicalExpression";
  operator: "||" | "&&" | "??";
  left: Expression;
  right: Expression;
}

示例:

代码语言:javascript
复制
x && y

3.17. Binary operations——SpreadElement

AST:A logical operator expression.

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

示例:

代码语言:javascript
复制
[...x, ...y]

3.18. Binary operations——ArgumentPlaceholder

proposal-partial-application:

  • This proposal introduces a new syntax using the ? token in an argument list which allows you to partially apply an argument list to a call expression by acting as a placeholder for an argument.
  • The ? placeholder token can be supplied one or more times at the top level of the Arguments of a CallExpression, CallMemberExpression, or SuperCall (e.g. f(?) or o.f(?)), or in place of the Expression of a TemplateMiddleList (e.g. f`before${?}after`). ? is not an expression, rather it is a syntactic element that indicates special behavior (much like how `...` AssignmentExpression indicates spread, yet is itself not an expression).
  • The ? placeholder token can only be used in an argument list of a call expression, or as the only token in a placeholder of a template expression or tagged template expression. When present, the result of the call is a new function with a parameter for each ? token in the argument list. Any non-placeholder expression in the argument list becomes fixed in its position.
代码语言:javascript
复制
function add(x, y) { return x + y; }

const addOne = add(1, ?); // apply from the left
addOne(2); // 3

const addTen = add(?, 10); // apply from the right
addTen(2); // 12  

AST:

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

示例:

代码语言:javascript
复制
const g = f(?, 1, ?);

3.19. Binary operations——MemberExpression

AST:A member expression. If computed is true, the node corresponds to a computed (a[b]) member expression and property is an Expression. If computed is false, the node corresponds to a static (a.b) member expression and property is an Identifier or a PrivateName.

代码语言:javascript
复制
export interface MemberExpression extends BaseNode {
  type: "MemberExpression";
  object: Expression;
  property: Expression | Identifier | PrivateName;
  computed: boolean;
  optional: true | false | null;
}

示例:

代码语言:javascript
复制
a.b;
a[b];

3.20. Binary operations——BindExpression

ES7:

  • Babel 5.4 was just released and with it comes support for a new experimental ES7 syntax proposed by Kevin Smith (@zenparsing) and implemented in Babel by Ingvar Stepanyan (@RReverser).
  • The function bind syntax introduces a new operator :: which performs function binding and method extraction.
  • The function bind syntax introduces a new operator :: which performs function binding and method extraction.

ES7——Demo:

代码语言:javascript
复制
经典写法:
  [].map.call(someNodeList, myFn);
  Array.from(someNodeList).map(myFn);
ES7写法:
  someNodeList::map(myFn);  

AST:

  • If object is null, then callee should be a MemberExpression.
代码语言:javascript
复制
export interface BindExpression extends BaseNode {
  type: "BindExpression";
  object: Expression;
  callee: Expression;
}

示例:

代码语言:javascript
复制
a::b

3.21. ConditionalExpression

AST:A conditional expression, i.e., a ternary ?/: expression.

代码语言:javascript
复制
export interface ConditionalExpression extends BaseNode {
  type: "ConditionalExpression";
  test: Expression;
  consequent: Expression;
  alternate: Expression;
}

示例:

代码语言:javascript
复制
a ? b : c

3.22. CallExpression

AST:A function or method call expression. When the callee is Import, the arguments must have only one Expression element.

代码语言:javascript
复制
export interface CallExpression extends BaseNode {
  type: "CallExpression";
  callee: Expression | V8IntrinsicIdentifier;
  arguments: Array<Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder>;
  optional: true | false | null;
  typeArguments: TypeParameterInstantiation | null;
  typeParameters: TSTypeParameterInstantiation | null;
}

示例:

代码语言:javascript
复制
fn()

3.23. NewExpression

AST:A new expression.

代码语言:javascript
复制
export interface NewExpression extends BaseNode {
  type: "NewExpression";
  callee: Expression | V8IntrinsicIdentifier;
  arguments: Array<Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder>;
  optional: true | false | null;
  typeArguments: TypeParameterInstantiation | null;
  typeParameters: TSTypeParameterInstantiation | null;
}

示例:

代码语言:javascript
复制
new App(1, 2)

3.24. SequenceExpression

AST:A sequence expression, i.e., a comma-separated sequence of expressions.

代码语言:javascript
复制
export interface SequenceExpression extends BaseNode {
  type: "SequenceExpression";
  expressions: Array<Expression>;
}

示例:

代码语言:javascript
复制
a,b,c,d;

3.24. ParenthesizedExpression

AST:An expression wrapped by parentheses. By default @babel/parser does not create this node, unless the createParenthesizedExpressions: true option is passed.

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

示例:

代码语言:javascript
复制
//TODO 暂时还不太理解是干啥的

3.25. DoExpression

proposal-do-expressions:

  • The do { .. } expression executes a block (with one or many statements in it), and the final statement completion value inside the block becomes the completion value of the do expression.
  • One of the most useful usage of the do expression is inside JSX. If we want to conditionally display a component we usually have to call another function which would implement the condition and return the correct value, for example:
代码语言:javascript
复制
const getColoredComponent = color => {
  if(color === 'blue') { return <BlueComponent/>; }
  if(color === 'red') { return <RedComponent/>; }
  if(color === 'green') { return <GreenComponent/>; }
}

const Component = props =>
  <div className='myComponent'>
    {getColoredComponent()}
  </div>
;

// Using a do expression you can add logic inside JSX:

const Component = props =>
  <div className='myComponent'>
    {do {
      if(color === 'blue') { <BlueComponent/>; }
      else if(color === 'red') { <RedComponent/>; }
      else if(color === 'green') { <GreenComponent/>; }
    }}
  </div>
;

AST:

代码语言:javascript
复制
export interface DoExpression extends BaseNode {
  type: "DoExpression";
  body: BlockStatement;
}

示例:

代码语言:javascript
复制
let a = do {
  if(x > 10) {
    'big';
  } else {
    'small';
  }
};

参考资料1:

Expressions: https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md#expressions Function Bind Syntax: https://babeljs.io/blog/2015/05/14/function-bind do-expressions: https://github.com/tc39/proposal-do-expressions https://babeljs.io/docs/en/babel-plugin-proposal-do-expressions

参考资料2:

Partial Application Syntax for ECMAScript: https://github.com/tc39/proposal-partial-application JavaScript Records & Tuples Proposal: https://github.com/tc39/proposal-record-tuple

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

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

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

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

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