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
- ObjectMember
- RecordExpression
- TupleExpression
- FunctionExpression
- Unary operations
- UnaryExpression
- UnaryOperator
- UpdateExpression
- UpdateOperator
- UnaryExpression
- Binary operations
- BinaryExpression
- BinaryOperator
- AssignmentExpression
- AssignmentOperator
- LogicalExpression
- LogicalOperator
- SpreadElement
- ArgumentPlaceholder
- MemberExpression
- BindExpression
- BinaryExpression
- 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.
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.
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:
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