mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 21:54:36 +03:00
Make deserialization fast (#314)
swc_ecma_ast: - add deserialization benchmark ast_node: - #[ast_node] on enum now implements faster deserialization
This commit is contained in:
parent
b4a391b3a7
commit
ed100700f1
@ -20,7 +20,7 @@ pub use self::{
|
||||
pos::*,
|
||||
source_map::{FileLines, FileLoader, FileName, FilePathMapping, SourceMap, SpanSnippetError},
|
||||
};
|
||||
pub use ast_node::{ast_node, Fold, FromVariant, Spanned};
|
||||
pub use ast_node::{ast_node, DeserializeEnum, Fold, FromVariant, Spanned};
|
||||
use serde::Serialize;
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -7,3 +7,9 @@ pub struct Node<T> {
|
||||
#[serde(flatten)]
|
||||
pub node: T,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Type {
|
||||
#[serde(rename = "type")]
|
||||
pub ty: String,
|
||||
}
|
||||
|
1442
ecmascript/ast/benches/module-1.json
Normal file
1442
ecmascript/ast/benches/module-1.json
Normal file
File diff suppressed because it is too large
Load Diff
539
ecmascript/ast/benches/module-2.json
Normal file
539
ecmascript/ast/benches/module-2.json
Normal file
@ -0,0 +1,539 @@
|
||||
{
|
||||
"type": "Module",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 23,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "FunctionDeclaration",
|
||||
"identifier": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "asyncGeneratorStep",
|
||||
"optional": false
|
||||
},
|
||||
"declare": false,
|
||||
"params": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "gen",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "resolve",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "reject",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "_next",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "_throw",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "key",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "arg",
|
||||
"optional": false
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": {
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "TryStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"block": {
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"kind": "var",
|
||||
"declare": false,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "info",
|
||||
"optional": false
|
||||
},
|
||||
"init": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "gen",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "key",
|
||||
"optional": false
|
||||
},
|
||||
"computed": true
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "arg",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"kind": "var",
|
||||
"declare": false,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "value",
|
||||
"optional": false
|
||||
},
|
||||
"init": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "info",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "value",
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"handler": {
|
||||
"type": "CatchClause",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"param": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "error",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "reject",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "error",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
},
|
||||
{
|
||||
"type": "ReturnStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "IfStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"test": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "info",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "done",
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"consequent": {
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "resolve",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "value",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"alternate": {
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "Promise",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "resolve",
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "value",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "then",
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "_next",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"expr": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 0,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "_throw",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"generator": false,
|
||||
"async": false
|
||||
}
|
||||
]
|
||||
}
|
25
ecmascript/ast/benches/serde.rs
Normal file
25
ecmascript/ast/benches/serde.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate serde_json;
|
||||
extern crate swc_ecma_ast;
|
||||
extern crate test;
|
||||
|
||||
use swc_ecma_ast::Module;
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn module_1(b: &mut Bencher) {
|
||||
const SRC: &str = include_str!("module-1.json");
|
||||
b.bytes = SRC.len() as _;
|
||||
|
||||
b.iter(|| test::black_box(serde_json::from_str::<Module>(SRC).unwrap()))
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn module_2(b: &mut Bencher) {
|
||||
const SRC: &str = include_str!("module-2.json");
|
||||
b.bytes = SRC.len() as _;
|
||||
|
||||
b.iter(|| test::black_box(serde_json::from_str::<Module>(SRC).unwrap()))
|
||||
}
|
@ -45,13 +45,19 @@ pub struct Class {
|
||||
|
||||
#[ast_node]
|
||||
pub enum ClassMember {
|
||||
#[tag("Constructor")]
|
||||
Constructor(Constructor),
|
||||
/// `es2015`
|
||||
#[tag("ClassMethod")]
|
||||
Method(ClassMethod),
|
||||
#[tag("PrivateMethod")]
|
||||
PrivateMethod(PrivateMethod),
|
||||
/// stage 0 / Typescript
|
||||
#[tag("ClassProperty")]
|
||||
ClassProp(ClassProp),
|
||||
#[tag("PrivateProperty")]
|
||||
PrivateProp(PrivateProp),
|
||||
#[tag("TsIndexSignature")]
|
||||
TsIndexSignature(TsIndexSignature),
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,19 @@ use swc_common::{ast_node, Span};
|
||||
|
||||
#[ast_node]
|
||||
pub enum Decl {
|
||||
#[tag("ClassDeclaration")]
|
||||
Class(ClassDecl),
|
||||
#[tag("FunctionDeclaration")]
|
||||
Fn(FnDecl),
|
||||
#[tag("VariableDeclaration")]
|
||||
Var(VarDecl),
|
||||
#[tag("TsInterfaceDeclaration")]
|
||||
TsInterface(TsInterfaceDecl),
|
||||
#[tag("TsTypeAliasDeclaration")]
|
||||
TsTypeAlias(TsTypeAliasDecl),
|
||||
#[tag("TsEnumDeclaration")]
|
||||
TsEnum(TsEnumDecl),
|
||||
#[tag("TsModuleDeclaration")]
|
||||
TsModule(TsModuleDecl),
|
||||
}
|
||||
|
||||
|
@ -20,21 +20,29 @@ use swc_common::{ast_node, Span, Spanned, DUMMY_SP};
|
||||
|
||||
#[ast_node]
|
||||
pub enum Expr {
|
||||
#[tag("ThisExpression")]
|
||||
This(ThisExpr),
|
||||
|
||||
#[tag("ArrayExpression")]
|
||||
Array(ArrayLit),
|
||||
|
||||
#[tag("ObjectExpression")]
|
||||
Object(ObjectLit),
|
||||
|
||||
#[tag("FunctionExpression")]
|
||||
Fn(FnExpr),
|
||||
|
||||
#[tag("UnaryExpression")]
|
||||
Unary(UnaryExpr),
|
||||
|
||||
/// `++v`, `--v`, `v++`, `v--`
|
||||
#[tag("UpdateExpression")]
|
||||
Update(UpdateExpr),
|
||||
|
||||
#[tag("BinaryExpression")]
|
||||
Bin(BinExpr),
|
||||
|
||||
#[tag("AssignmentExpression")]
|
||||
Assign(AssignExpr),
|
||||
|
||||
//
|
||||
@ -48,56 +56,86 @@ pub enum Expr {
|
||||
/// 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.
|
||||
#[tag("MemberExpression")]
|
||||
Member(MemberExpr),
|
||||
|
||||
/// true ? 'a' : 'b'
|
||||
#[tag("ConditionalExpression")]
|
||||
Cond(CondExpr),
|
||||
|
||||
#[tag("CallExpression")]
|
||||
Call(CallExpr),
|
||||
|
||||
/// `new Cat()`
|
||||
#[tag("NewExpression")]
|
||||
New(NewExpr),
|
||||
|
||||
#[tag("SequenceExpression")]
|
||||
Seq(SeqExpr),
|
||||
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("StringLiteral")]
|
||||
#[tag("BooleanLiteral")]
|
||||
#[tag("NullLiteral")]
|
||||
#[tag("NumericLiteral")]
|
||||
#[tag("RegExpLiteral")]
|
||||
#[tag("JSXText")]
|
||||
Lit(Lit),
|
||||
|
||||
#[tag("TemplateLiteral")]
|
||||
Tpl(Tpl),
|
||||
|
||||
#[tag("TaggedTemplateExpression")]
|
||||
TaggedTpl(TaggedTpl),
|
||||
|
||||
#[tag("ArrowFunctionExpression")]
|
||||
Arrow(ArrowExpr),
|
||||
|
||||
#[tag("ClassExpression")]
|
||||
Class(ClassExpr),
|
||||
|
||||
#[tag("YieldExpression")]
|
||||
Yield(YieldExpr),
|
||||
|
||||
#[tag("MetaProperty")]
|
||||
MetaProp(MetaPropExpr),
|
||||
|
||||
#[tag("AwaitExpression")]
|
||||
Await(AwaitExpr),
|
||||
|
||||
#[tag("ParenthesisExpression")]
|
||||
Paren(ParenExpr),
|
||||
|
||||
#[tag("JSXMemberExpression")]
|
||||
JSXMebmer(JSXMemberExpr),
|
||||
|
||||
#[tag("JSXNamespacedName")]
|
||||
JSXNamespacedName(JSXNamespacedName),
|
||||
|
||||
#[tag("JSXEmptyExpression")]
|
||||
JSXEmpty(JSXEmptyExpr),
|
||||
|
||||
#[tag("JSXElement")]
|
||||
JSXElement(JSXElement),
|
||||
|
||||
#[tag("JSXFragment")]
|
||||
JSXFragment(JSXFragment),
|
||||
|
||||
#[tag("TsTypeAssertion")]
|
||||
TsTypeAssertion(TsTypeAssertion),
|
||||
|
||||
#[tag("TsNonNullExpression")]
|
||||
TsNonNull(TsNonNullExpr),
|
||||
|
||||
#[tag("TsTypeCastExpression")]
|
||||
TsTypeCast(TsTypeCastExpr),
|
||||
|
||||
#[tag("TsAsExpression")]
|
||||
TsAs(TsAsExpr),
|
||||
|
||||
#[tag("PrivateName")]
|
||||
PrivateName(PrivateName),
|
||||
}
|
||||
|
||||
@ -130,9 +168,12 @@ pub struct ObjectLit {
|
||||
|
||||
#[ast_node]
|
||||
pub enum PropOrSpread {
|
||||
Prop(Box<Prop>),
|
||||
/// Spread properties, e.g., `{a: 1, ...obj, b: 2}`.
|
||||
#[tag("SpreadElement")]
|
||||
Spread(SpreadElement),
|
||||
|
||||
#[tag("*")]
|
||||
Prop(Box<Prop>),
|
||||
}
|
||||
|
||||
#[ast_node("SpreadElement")]
|
||||
@ -403,8 +444,18 @@ pub struct ParenExpr {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum ExprOrSuper {
|
||||
#[tag("Super")]
|
||||
Super(Super),
|
||||
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
Super(Span),
|
||||
}
|
||||
|
||||
#[ast_node("Super")]
|
||||
#[derive(Copy)]
|
||||
pub struct Super {
|
||||
#[serde(default)]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -429,14 +480,53 @@ impl Spanned for ExprOrSpread {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum BlockStmtOrExpr {
|
||||
#[tag("BlockStatement")]
|
||||
BlockStmt(BlockStmt),
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum PatOrExpr {
|
||||
// order is important for proper deserialization.
|
||||
#[tag("ThisExpression")]
|
||||
#[tag("ArrayExpression")]
|
||||
#[tag("ObjectExpression")]
|
||||
#[tag("FunctionExpression")]
|
||||
#[tag("UnaryExpression")]
|
||||
#[tag("UpdateExpression")]
|
||||
#[tag("BinaryExpression")]
|
||||
#[tag("AssignmentExpression")]
|
||||
#[tag("MemberExpression")]
|
||||
#[tag("ConditionalExpression")]
|
||||
#[tag("CallExpression")]
|
||||
#[tag("NewExpression")]
|
||||
#[tag("SequenceExpression")]
|
||||
#[tag("StringLiteral")]
|
||||
#[tag("BooleanLiteral")]
|
||||
#[tag("NullLiteral")]
|
||||
#[tag("NumericLiteral")]
|
||||
#[tag("RegExpLiteral")]
|
||||
#[tag("JSXText")]
|
||||
#[tag("TemplateLiteral")]
|
||||
#[tag("TaggedTemplateLiteral")]
|
||||
#[tag("ArrowFunctionExpression")]
|
||||
#[tag("ClassExpression")]
|
||||
#[tag("YieldExpression")]
|
||||
#[tag("MetaProperty")]
|
||||
#[tag("AwaitExpression")]
|
||||
#[tag("ParenthesisExpression")]
|
||||
#[tag("JSXMemberExpression")]
|
||||
#[tag("JSXNamespacedName")]
|
||||
#[tag("JSXEmptyExpression")]
|
||||
#[tag("JSXElement")]
|
||||
#[tag("JSXFragment")]
|
||||
#[tag("TsTypeAssertion")]
|
||||
#[tag("TsNonNullExpression")]
|
||||
#[tag("TsTypeCastExpression")]
|
||||
#[tag("TsAsExpression")]
|
||||
#[tag("PrivateName")]
|
||||
Expr(Box<Expr>),
|
||||
#[tag("*")]
|
||||
Pat(Box<Pat>),
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ pub struct Function {
|
||||
|
||||
#[ast_node]
|
||||
pub enum PatOrTsParamProp {
|
||||
Pat(Pat),
|
||||
#[tag("TsParameterProperty")]
|
||||
TsParamProp(TsParamProp),
|
||||
#[tag("*")]
|
||||
Pat(Pat),
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ use swc_common::{ast_node, Span};
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum JSXObject {
|
||||
#[tag("JSXMemberExpression")]
|
||||
JSXMemberExpr(Box<JSXMemberExpr>),
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
}
|
||||
|
||||
@ -53,7 +55,9 @@ pub struct JSXExprContainer {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum JSXExpr {
|
||||
#[tag("JSXEmptyExpression")]
|
||||
JSXEmptyExpr(JSXEmptyExpr),
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
||||
@ -66,8 +70,11 @@ pub struct JSXSpreadChild {
|
||||
|
||||
#[ast_node]
|
||||
pub enum JSXElementName {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
#[tag("JSXMemberExpression")]
|
||||
JSXMemberExpr(JSXMemberExpr),
|
||||
#[tag("JSXNamespacedName")]
|
||||
JSXNamespacedName(JSXNamespacedName),
|
||||
}
|
||||
|
||||
@ -97,7 +104,9 @@ pub struct JSXOpeningElement {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum JSXAttrOrSpread {
|
||||
#[tag("JSXAttribute")]
|
||||
JSXAttr(JSXAttr),
|
||||
#[tag("SpreadElement")]
|
||||
SpreadElement(SpreadElement),
|
||||
}
|
||||
|
||||
@ -120,15 +129,29 @@ pub struct JSXAttr {
|
||||
|
||||
#[ast_node]
|
||||
pub enum JSXAttrName {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
#[tag("JSXNamespacedName")]
|
||||
JSXNamespacedName(JSXNamespacedName),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum JSXAttrValue {
|
||||
#[tag("StringLiteral")]
|
||||
#[tag("BooleanLiteral")]
|
||||
#[tag("NullLiteral")]
|
||||
#[tag("NumericLiteral")]
|
||||
#[tag("RegExpLiteral")]
|
||||
#[tag("JSXText")]
|
||||
Lit(Lit),
|
||||
|
||||
#[tag("JSXExpressionContainer")]
|
||||
JSXExprContainer(JSXExprContainer),
|
||||
|
||||
#[tag("JSXElement")]
|
||||
JSXElement(Box<JSXElement>),
|
||||
|
||||
#[tag("JSXFragment")]
|
||||
JSXFragment(JSXFragment),
|
||||
}
|
||||
|
||||
@ -151,10 +174,19 @@ pub struct JSXElement {
|
||||
|
||||
#[ast_node]
|
||||
pub enum JSXElementChild {
|
||||
#[tag("JSXText")]
|
||||
JSXText(JSXText),
|
||||
|
||||
#[tag("JSXExpressionContainer")]
|
||||
JSXExprContainer(JSXExprContainer),
|
||||
|
||||
#[tag("JSXSpreadChild")]
|
||||
JSXSpreadChild(JSXSpreadChild),
|
||||
|
||||
#[tag("JSXElement")]
|
||||
JSXElement(Box<JSXElement>),
|
||||
|
||||
#[tag("JSXFragment")]
|
||||
JSXFragment(JSXFragment),
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,8 @@ pub use self::{
|
||||
expr::{
|
||||
ArrayLit, ArrowExpr, AssignExpr, AwaitExpr, BinExpr, BlockStmtOrExpr, CallExpr, ClassExpr,
|
||||
CondExpr, Expr, ExprOrSpread, ExprOrSuper, FnExpr, MemberExpr, MetaPropExpr, NewExpr,
|
||||
ObjectLit, ParenExpr, PatOrExpr, PropOrSpread, SeqExpr, SpreadElement, TaggedTpl, ThisExpr,
|
||||
Tpl, TplElement, UnaryExpr, UpdateExpr, YieldExpr,
|
||||
ObjectLit, ParenExpr, PatOrExpr, PropOrSpread, SeqExpr, SpreadElement, Super, TaggedTpl,
|
||||
ThisExpr, Tpl, TplElement, UnaryExpr, UpdateExpr, YieldExpr,
|
||||
},
|
||||
function::{Function, PatOrTsParamProp},
|
||||
ident::{Ident, IdentExt, PrivateName},
|
||||
|
@ -5,16 +5,22 @@ use swc_common::{ast_node, Span};
|
||||
|
||||
#[ast_node]
|
||||
pub enum Lit {
|
||||
#[tag("StringLiteral")]
|
||||
Str(Str),
|
||||
|
||||
#[tag("BooleanLiteral")]
|
||||
Bool(Bool),
|
||||
|
||||
#[tag("NullLiteral")]
|
||||
Null(Null),
|
||||
|
||||
#[tag("NumericLiteral")]
|
||||
Num(Number),
|
||||
|
||||
#[tag("RegExpLiteral")]
|
||||
Regex(Regex),
|
||||
|
||||
#[tag("JSXText")]
|
||||
JSXText(JSXText),
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,18 @@ pub struct Script {
|
||||
|
||||
#[ast_node]
|
||||
pub enum ModuleItem {
|
||||
Stmt(Stmt),
|
||||
#[tag("ImportDeclaration")]
|
||||
#[tag("ExportDeclaration")]
|
||||
#[tag("ExportNamedDeclaration")]
|
||||
#[tag("ExportDefaultDeclaration")]
|
||||
#[tag("ExportDefaultExpression")]
|
||||
#[tag("ExportAllDeclaration")]
|
||||
#[tag("TsImportEqualsDeclaration")]
|
||||
#[tag("TsExportAssignment")]
|
||||
#[tag("TsNamespaceExportDeclaration")]
|
||||
ModuleDecl(ModuleDecl),
|
||||
#[tag("*")]
|
||||
Stmt(Stmt),
|
||||
}
|
||||
|
||||
// This test ensures that FnDecl can be deserialized if type field is present
|
||||
|
@ -9,16 +9,31 @@ use swc_common::{ast_node, Span};
|
||||
|
||||
#[ast_node]
|
||||
pub enum ModuleDecl {
|
||||
#[tag("ImportDeclaration")]
|
||||
Import(ImportDecl),
|
||||
|
||||
#[tag("ExportDeclaration")]
|
||||
ExportDecl(ExportDecl),
|
||||
|
||||
#[tag("ExportNamedDeclaration")]
|
||||
ExportNamed(NamedExport),
|
||||
|
||||
#[tag("ExportDefaultDeclaration")]
|
||||
ExportDefaultDecl(ExportDefaultDecl),
|
||||
|
||||
#[tag("ExportDefaultExpression")]
|
||||
ExportDefaultExpr(ExportDefaultExpr),
|
||||
|
||||
#[tag("ExportAllDeclaration")]
|
||||
ExportAll(ExportAll),
|
||||
|
||||
#[tag("TsImportEqualsDeclaration")]
|
||||
TsImportEquals(TsImportEqualsDecl),
|
||||
|
||||
#[tag("TsExportAssignment")]
|
||||
TsExportAssignment(TsExportAssignment),
|
||||
|
||||
#[tag("TsNamespaceExportDeclaration")]
|
||||
TsNamespaceExport(TsNamespaceExportDecl),
|
||||
}
|
||||
|
||||
@ -85,17 +100,23 @@ pub struct ExportDefaultDecl {
|
||||
|
||||
#[ast_node]
|
||||
pub enum DefaultDecl {
|
||||
#[tag("ClassExpression")]
|
||||
Class(ClassExpr),
|
||||
|
||||
#[tag("FunctionExpression")]
|
||||
Fn(FnExpr),
|
||||
|
||||
#[tag("TsInterfaceDeclaration")]
|
||||
TsInterfaceDecl(TsInterfaceDecl),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum ImportSpecifier {
|
||||
#[tag("ImportSpecifier")]
|
||||
Specific(ImportSpecific),
|
||||
#[tag("ImportDefaultSpecifier")]
|
||||
Default(ImportDefault),
|
||||
#[tag("ImportNamespaceSpecifier")]
|
||||
Namespace(ImportStarAs),
|
||||
}
|
||||
|
||||
@ -131,10 +152,13 @@ pub struct ImportSpecific {
|
||||
|
||||
#[ast_node]
|
||||
pub enum ExportSpecifier {
|
||||
#[tag("ExportNamespaceSpecifer")]
|
||||
Namespace(NamespaceExportSpecifier),
|
||||
|
||||
#[tag("ExportDefaultSpecifier")]
|
||||
Default(DefaultExportSpecifier),
|
||||
|
||||
#[tag("ExportSpecifier")]
|
||||
Named(NamedExportSpecifier),
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,23 @@ use swc_common::{ast_node, Span};
|
||||
|
||||
#[ast_node]
|
||||
pub enum Pat {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("ArrayPattern")]
|
||||
Array(ArrayPat),
|
||||
|
||||
#[tag("RestElement")]
|
||||
Rest(RestPat),
|
||||
|
||||
#[tag("ObjectPattern")]
|
||||
Object(ObjectPat),
|
||||
|
||||
#[tag("AssignmentPattern")]
|
||||
Assign(AssignPat),
|
||||
|
||||
/// Only for for-in / for-of loops. This is *syntatically* valid.
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
||||
@ -87,8 +93,13 @@ pub struct RestPat {
|
||||
|
||||
#[ast_node]
|
||||
pub enum ObjectPatProp {
|
||||
#[tag("KeyValuePatternProperty")]
|
||||
KeyValue(KeyValuePatProp),
|
||||
|
||||
#[tag("AssignmentPatternProperty")]
|
||||
Assign(AssignPatProp),
|
||||
|
||||
#[tag("RestElement")]
|
||||
Rest(RestPat),
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,24 @@ use swc_common::{ast_node, Span};
|
||||
#[ast_node]
|
||||
pub enum Prop {
|
||||
/// `a` in `{ a, }`
|
||||
#[tag("Identifier")]
|
||||
Shorthand(Ident),
|
||||
|
||||
/// `key: value` in `{ key: value, }`
|
||||
#[tag("KeyValueProperty")]
|
||||
KeyValue(KeyValueProp),
|
||||
|
||||
/// This is **invalid** for object literal.
|
||||
#[tag("AssignmentProperty")]
|
||||
Assign(AssignProp),
|
||||
|
||||
#[tag("GetterProperty")]
|
||||
Getter(GetterProp),
|
||||
|
||||
#[tag("SetterProperty")]
|
||||
Setter(SetterProp),
|
||||
|
||||
#[tag("MethodProperty")]
|
||||
Method(MethodProp),
|
||||
}
|
||||
|
||||
@ -67,10 +77,14 @@ pub struct MethodProp {
|
||||
|
||||
#[ast_node]
|
||||
pub enum PropName {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
/// String literal.
|
||||
#[tag("StringLiteral")]
|
||||
Str(Str),
|
||||
/// Numeric literal.
|
||||
#[tag("NumericLiteral")]
|
||||
Num(Number),
|
||||
#[tag("*")]
|
||||
Computed(Box<Expr>),
|
||||
}
|
||||
|
@ -18,44 +18,69 @@ pub struct BlockStmt {
|
||||
|
||||
#[ast_node]
|
||||
pub enum Stmt {
|
||||
Expr(Box<Expr>),
|
||||
|
||||
#[tag("BlockStatement")]
|
||||
Block(BlockStmt),
|
||||
|
||||
#[tag("EmptyStatement")]
|
||||
Empty(EmptyStmt),
|
||||
|
||||
#[tag("DebuggerStatement")]
|
||||
Debugger(DebuggerStmt),
|
||||
|
||||
#[tag("WithStatement")]
|
||||
With(WithStmt),
|
||||
|
||||
#[tag("ReturnStatement")]
|
||||
Return(ReturnStmt),
|
||||
|
||||
#[tag("LabeledStatement")]
|
||||
Labeled(LabeledStmt),
|
||||
|
||||
#[tag("BreakStatement")]
|
||||
Break(BreakStmt),
|
||||
|
||||
#[tag("ContinueStatement")]
|
||||
Continue(ContinueStmt),
|
||||
|
||||
#[tag("IfStatement")]
|
||||
If(IfStmt),
|
||||
|
||||
#[tag("SwitchStatement")]
|
||||
Switch(SwitchStmt),
|
||||
|
||||
#[tag("ThrowStatement")]
|
||||
Throw(ThrowStmt),
|
||||
|
||||
/// A try statement. If handler is null then finalizer must be a BlockStmt.
|
||||
#[tag("TryStatement")]
|
||||
Try(TryStmt),
|
||||
|
||||
#[tag("WhileStatement")]
|
||||
While(WhileStmt),
|
||||
|
||||
#[tag("DoWhileStatement")]
|
||||
DoWhile(DoWhileStmt),
|
||||
|
||||
#[tag("ForStatement")]
|
||||
For(ForStmt),
|
||||
|
||||
#[tag("ForInStatement")]
|
||||
ForIn(ForInStmt),
|
||||
|
||||
#[tag("ForOfStatement")]
|
||||
ForOf(ForOfStmt),
|
||||
|
||||
#[tag("ClassDeclaration")]
|
||||
#[tag("FunctionDeclaration")]
|
||||
#[tag("VariableDeclaration")]
|
||||
#[tag("TsInterfaceDeclaration")]
|
||||
#[tag("TsTypeAliasDeclaration")]
|
||||
#[tag("TsEnumDeclaration")]
|
||||
#[tag("TsModuleDeclaration")]
|
||||
Decl(Decl),
|
||||
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
||||
#[ast_node("EmptyStatement")]
|
||||
@ -244,13 +269,19 @@ pub struct CatchClause {
|
||||
|
||||
#[ast_node]
|
||||
pub enum VarDeclOrPat {
|
||||
#[tag("VariableDeclaration")]
|
||||
VarDecl(VarDecl),
|
||||
|
||||
#[tag("*")]
|
||||
Pat(Pat),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum VarDeclOrExpr {
|
||||
#[tag("VariableDeclaration")]
|
||||
VarDecl(VarDecl),
|
||||
|
||||
#[tag("*")]
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
@ -77,7 +77,10 @@ pub struct TsParamProp {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsParamPropParam {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("AssignmentPattern")]
|
||||
Assign(AssignPat),
|
||||
}
|
||||
|
||||
@ -92,16 +95,28 @@ pub struct TsQualifiedName {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum TsEntityName {
|
||||
#[tag("TsQualifiedName")]
|
||||
TsQualifiedName(Box<TsQualifiedName>),
|
||||
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsSignatureDecl {
|
||||
#[tag("TsCallSignatureDeclaration")]
|
||||
TsCallSignatureDecl(TsCallSignatureDecl),
|
||||
|
||||
#[tag("TsConstructSignatureDeclaration")]
|
||||
TsConstructSignatureDecl(TsConstructSignatureDecl),
|
||||
|
||||
#[tag("TsMethodSignature")]
|
||||
TsMethodSignature(TsMethodSignature),
|
||||
|
||||
#[tag("TsFunctionType")]
|
||||
TsFnType(TsFnType),
|
||||
|
||||
#[tag("TsConstructorType")]
|
||||
TsConstructorType(TsConstructorType),
|
||||
}
|
||||
|
||||
@ -111,10 +126,19 @@ pub enum TsSignatureDecl {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsTypeElement {
|
||||
#[tag("TsCallSignatureDeclaration")]
|
||||
TsCallSignatureDecl(TsCallSignatureDecl),
|
||||
|
||||
#[tag("TsConstructSignatureDeclaration")]
|
||||
TsConstructSignatureDecl(TsConstructSignatureDecl),
|
||||
|
||||
#[tag("TsPropertySignature")]
|
||||
TsPropertySignature(TsPropertySignature),
|
||||
|
||||
#[tag("TsMethodSignature")]
|
||||
TsMethodSignature(TsMethodSignature),
|
||||
|
||||
#[tag("TsIndexSignature")]
|
||||
TsIndexSignature(TsIndexSignature),
|
||||
}
|
||||
|
||||
@ -205,30 +229,71 @@ pub struct TsIndexSignature {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsType {
|
||||
#[tag("TsKeywordType")]
|
||||
TsKeywordType(TsKeywordType),
|
||||
|
||||
#[tag("TsThisType")]
|
||||
TsThisType(TsThisType),
|
||||
|
||||
#[tag("TsFunctionType")]
|
||||
#[tag("TsConstructorType")]
|
||||
TsFnOrConstructorType(TsFnOrConstructorType),
|
||||
|
||||
#[tag("TsTypeReference")]
|
||||
TsTypeRef(TsTypeRef),
|
||||
|
||||
#[tag("TsTypeQuery")]
|
||||
TsTypeQuery(TsTypeQuery),
|
||||
|
||||
#[tag("TsTypeLiteral")]
|
||||
TsTypeLit(TsTypeLit),
|
||||
|
||||
#[tag("TsArrayType")]
|
||||
TsArrayType(TsArrayType),
|
||||
|
||||
#[tag("TsTupleType")]
|
||||
TsTupleType(TsTupleType),
|
||||
|
||||
#[tag("TsOptionalType")]
|
||||
TsOptionalType(TsOptionalType),
|
||||
|
||||
#[tag("TsRestType")]
|
||||
TsRestType(TsRestType),
|
||||
|
||||
#[tag("TsUnionType")]
|
||||
#[tag("TsIntersectionType")]
|
||||
TsUnionOrIntersectionType(TsUnionOrIntersectionType),
|
||||
|
||||
#[tag("TsConditionalType")]
|
||||
TsConditionalType(TsConditionalType),
|
||||
|
||||
#[tag("TsInferType")]
|
||||
TsInferType(TsInferType),
|
||||
|
||||
#[tag("TsParenthesizedType")]
|
||||
TsParenthesizedType(TsParenthesizedType),
|
||||
|
||||
#[tag("TsTypeOperator")]
|
||||
TsTypeOperator(TsTypeOperator),
|
||||
|
||||
#[tag("TsIndexedAccessType")]
|
||||
TsIndexedAccessType(TsIndexedAccessType),
|
||||
|
||||
#[tag("TsMappedType")]
|
||||
TsMappedType(TsMappedType),
|
||||
|
||||
#[tag("TsLiteralType")]
|
||||
TsLitType(TsLitType),
|
||||
|
||||
#[tag("TsTypePredicate")]
|
||||
TsTypePredicate(TsTypePredicate),
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsFnOrConstructorType {
|
||||
#[tag("TsFunctionType")]
|
||||
TsFnType(TsFnType),
|
||||
#[tag("TsConstructorType")]
|
||||
TsConstructorType(TsConstructorType),
|
||||
}
|
||||
|
||||
@ -311,8 +376,13 @@ pub struct TsThisType {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsFnParam {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("RestElement")]
|
||||
Rest(RestPat),
|
||||
|
||||
#[tag("ObjectPattern")]
|
||||
Object(ObjectPat),
|
||||
}
|
||||
|
||||
@ -360,7 +430,10 @@ pub struct TsTypePredicate {
|
||||
#[ast_node]
|
||||
#[allow(variant_size_differences)]
|
||||
pub enum TsThisTypeOrIdent {
|
||||
#[tag("TsThisType")]
|
||||
TsThisType(TsThisType),
|
||||
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
}
|
||||
|
||||
@ -411,7 +484,10 @@ pub struct TsRestType {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsUnionOrIntersectionType {
|
||||
#[tag("TsUnionType")]
|
||||
TsUnionType(TsUnionType),
|
||||
|
||||
#[tag("TsIntersectionType")]
|
||||
TsIntersectionType(TsIntersectionType),
|
||||
}
|
||||
|
||||
@ -570,8 +646,13 @@ pub struct TsLitType {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsLit {
|
||||
#[tag("NumericLiteral")]
|
||||
Number(Number),
|
||||
|
||||
#[tag("StringLiteral")]
|
||||
Str(Str),
|
||||
|
||||
#[tag("BooleanLiteral")]
|
||||
Bool(Bool),
|
||||
}
|
||||
|
||||
@ -641,7 +722,10 @@ pub struct TsEnumMember {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsEnumMemberId {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("StringLiteral")]
|
||||
Str(Str),
|
||||
}
|
||||
|
||||
@ -661,7 +745,10 @@ pub struct TsModuleDecl {
|
||||
/// its body.
|
||||
#[ast_node]
|
||||
pub enum TsNamespaceBody {
|
||||
#[tag("TsModuleBlock")]
|
||||
TsModuleBlock(TsModuleBlock),
|
||||
|
||||
#[tag("TsNamespaceDeclaration")]
|
||||
TsNamespaceDecl(TsNamespaceDecl),
|
||||
}
|
||||
|
||||
@ -685,7 +772,10 @@ pub struct TsNamespaceDecl {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsModuleName {
|
||||
#[tag("Identifier")]
|
||||
Ident(Ident),
|
||||
|
||||
#[tag("StringLiteral")]
|
||||
Str(Str),
|
||||
}
|
||||
|
||||
@ -701,7 +791,11 @@ pub struct TsImportEqualsDecl {
|
||||
|
||||
#[ast_node]
|
||||
pub enum TsModuleRef {
|
||||
#[tag("TsQualifiedName")]
|
||||
#[tag("Identifier")]
|
||||
TsEntityName(TsEntityName),
|
||||
|
||||
#[tag("TsExternalModuleReference")]
|
||||
TsExternalModuleRef(TsExternalModuleRef),
|
||||
}
|
||||
|
||||
|
@ -422,9 +422,13 @@ impl<'a> Emitter<'a> {
|
||||
pub fn emit_expr_or_super(&mut self, node: &ExprOrSuper) -> Result {
|
||||
match *node {
|
||||
ExprOrSuper::Expr(ref e) => emit!(e),
|
||||
ExprOrSuper::Super(span) => keyword!(span, "super"),
|
||||
ExprOrSuper::Super(ref n) => emit!(n),
|
||||
}
|
||||
}
|
||||
#[emitter]
|
||||
pub fn emit_super(&mut self, node: &Super) -> Result {
|
||||
keyword!(node.span, "super");
|
||||
}
|
||||
|
||||
#[emitter]
|
||||
pub fn emit_expr(&mut self, node: &Expr) -> Result {
|
||||
|
@ -423,7 +423,7 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
}
|
||||
|
||||
if eat!("super") {
|
||||
let base = ExprOrSuper::Super(span!(start));
|
||||
let base = ExprOrSuper::Super(Super { span: span!(start) });
|
||||
return self.parse_subscripts(base, true);
|
||||
}
|
||||
let obj = self.parse_primary_expr()?;
|
||||
@ -925,7 +925,7 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
|
||||
// `super()` can't be handled from parse_new_expr()
|
||||
if eat!("super") {
|
||||
let obj = ExprOrSuper::Super(span!(start));
|
||||
let obj = ExprOrSuper::Super(Super { span: span!(start) });
|
||||
return self.parse_subscripts(obj, false);
|
||||
}
|
||||
|
||||
@ -1161,7 +1161,9 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
|
||||
#[ast_node]
|
||||
pub(in crate::parser) enum PatOrExprOrSpread {
|
||||
#[tag("*")]
|
||||
Pat(Pat),
|
||||
#[tag("*")]
|
||||
ExprOrSpread(ExprOrSpread),
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,10 @@ impl<'a> Fold<Expr> for SuperCalleeFolder<'a> {
|
||||
prefix,
|
||||
}) => match *arg {
|
||||
Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Super(super_token),
|
||||
obj:
|
||||
ExprOrSuper::Super(Super {
|
||||
span: super_token, ..
|
||||
}),
|
||||
prop,
|
||||
..
|
||||
}) => {
|
||||
@ -139,12 +142,18 @@ impl<'a> Fold<Expr> for SuperCalleeFolder<'a> {
|
||||
right,
|
||||
}) => match left {
|
||||
PatOrExpr::Expr(box Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Super(super_token),
|
||||
obj:
|
||||
ExprOrSuper::Super(Super {
|
||||
span: super_token, ..
|
||||
}),
|
||||
prop,
|
||||
..
|
||||
}))
|
||||
| PatOrExpr::Pat(box Pat::Expr(box Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Super(super_token),
|
||||
obj:
|
||||
ExprOrSuper::Super(Super {
|
||||
span: super_token, ..
|
||||
}),
|
||||
prop,
|
||||
..
|
||||
}))) => self.super_to_set_call(super_token, false, prop, op, right),
|
||||
@ -160,7 +169,10 @@ impl<'a> Fold<Expr> for SuperCalleeFolder<'a> {
|
||||
|
||||
match n {
|
||||
Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Super(super_token),
|
||||
obj:
|
||||
ExprOrSuper::Super(Super {
|
||||
span: super_token, ..
|
||||
}),
|
||||
prop,
|
||||
computed,
|
||||
..
|
||||
|
@ -85,7 +85,7 @@ impl Fold<Expr> for ActualFolder {
|
||||
}
|
||||
let (this, callee) = match *callee {
|
||||
Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Super(span),
|
||||
obj: ExprOrSuper::Super(Super { span, .. }),
|
||||
..
|
||||
}) => (box Expr::This(ThisExpr { span }), callee),
|
||||
|
||||
|
@ -258,7 +258,7 @@ impl Decorators {
|
||||
vec![
|
||||
Stmt::Expr(box Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ExprOrSuper::Super(DUMMY_SP),
|
||||
callee: ExprOrSuper::Super(Super { span: DUMMY_SP }),
|
||||
args: vec![ExprOrSpread {
|
||||
spread: Some(DUMMY_SP),
|
||||
expr: box Expr::Ident(quote_ident!("args")),
|
||||
|
@ -841,7 +841,7 @@ pub fn default_constructor(has_super: bool) -> Constructor {
|
||||
stmts: if has_super {
|
||||
vec![Stmt::Expr(box Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ExprOrSuper::Super(DUMMY_SP),
|
||||
callee: ExprOrSuper::Super(Super { span: DUMMY_SP }),
|
||||
args: vec![ExprOrSpread {
|
||||
spread: Some(DUMMY_SP),
|
||||
expr: box Expr::Ident(quote_ident!(span, "args")),
|
||||
|
@ -28,5 +28,5 @@ features = ["derive", "fold", "parsing", "printing"]
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
swc_common = { version = "0.3", path = "../../common" }
|
||||
swc_common = { version = "0.3", path = "../../common", features = ["fold"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
@ -17,7 +17,181 @@ impl Parse for Args {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand(args: Args, i: DeriveInput) -> Vec<ItemImpl> {
|
||||
struct VariantAttr {
|
||||
_paren_token: token::Paren,
|
||||
tags: Punctuated<Lit, Token![,]>,
|
||||
}
|
||||
|
||||
impl Parse for VariantAttr {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let content;
|
||||
Ok(VariantAttr {
|
||||
_paren_token: parenthesized!(content in input),
|
||||
tags: content.parse_terminated(Lit::parse)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_enum(
|
||||
DeriveInput {
|
||||
generics,
|
||||
ident,
|
||||
data,
|
||||
..
|
||||
}: DeriveInput,
|
||||
) -> Vec<ItemImpl> {
|
||||
let data = match data {
|
||||
Data::Enum(data) => data,
|
||||
_ => unreachable!("expand_enum is called with none-enum item"),
|
||||
};
|
||||
|
||||
let deserialize = {
|
||||
let mut all_tags: Punctuated<_, token::Comma> = Default::default();
|
||||
let mut match_type = data
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| {
|
||||
let field_type = match variant.fields {
|
||||
Fields::Unnamed(ref fields) => {
|
||||
assert!(
|
||||
fields.unnamed.len() == 1,
|
||||
"#[ast_node] enum cannot contain variant with multiple fields"
|
||||
);
|
||||
|
||||
fields.unnamed.last().unwrap().into_value().ty.clone()
|
||||
}
|
||||
_ => {
|
||||
unreachable!("#[ast_node] enum cannot contain named fields or unit variant")
|
||||
}
|
||||
};
|
||||
let tags = variant
|
||||
.attrs
|
||||
.iter()
|
||||
.filter_map(|attr| -> Option<VariantAttr> {
|
||||
if !is_attr_name(attr, "tag") {
|
||||
return None;
|
||||
}
|
||||
let tags =
|
||||
parse2(attr.tts.clone()).expect("failed to parse #[tag] attribute");
|
||||
|
||||
Some(tags)
|
||||
})
|
||||
.flat_map(|v| v.tags)
|
||||
.collect::<Punctuated<_, token::Comma>>();
|
||||
|
||||
assert!(
|
||||
tags.len() >= 1,
|
||||
"All #[ast_node] enum variants have one or more tag"
|
||||
);
|
||||
if tags.len() == 1
|
||||
&& match tags.first().map(Pair::into_value) {
|
||||
Some(Lit::Str(s)) => &*s.value() == "*",
|
||||
_ => false,
|
||||
}
|
||||
{
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
Enum: &ident,
|
||||
Variant: &variant.ident,
|
||||
VariantFieldType: &field_type,
|
||||
},
|
||||
{
|
||||
if let Ok(v) = std::result::Result::map(
|
||||
<VariantFieldType as serde::Deserialize>::deserialize(
|
||||
serde::private::de::ContentRefDeserializer::<D::Error>::new(
|
||||
&content,
|
||||
),
|
||||
),
|
||||
Enum::Variant,
|
||||
) {
|
||||
return Ok(v);
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse()
|
||||
} else {
|
||||
for tag in tags.iter() {
|
||||
all_tags.push(tag.clone());
|
||||
}
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
Enum: &ident,
|
||||
Variant: &variant.ident,
|
||||
VariantFieldType: &field_type,
|
||||
tags,
|
||||
},
|
||||
{
|
||||
{
|
||||
const TAGS: &[&str] = &[tags];
|
||||
if TAGS.contains(&&*ty.ty) {
|
||||
if let Ok(v) = std::result::Result::map(
|
||||
<VariantFieldType as serde::Deserialize>::deserialize(
|
||||
serde::private::de::ContentRefDeserializer::<
|
||||
D::Error,
|
||||
>::new(
|
||||
&content
|
||||
),
|
||||
),
|
||||
Enum::Variant,
|
||||
) {
|
||||
return Ok(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<Expr>>();
|
||||
|
||||
let mut match_type_expr = Quote::new_call_site();
|
||||
for expr in match_type {
|
||||
match_type_expr = match_type_expr.quote_with(smart_quote!(Vars { expr }, { expr }));
|
||||
}
|
||||
|
||||
match_type_expr = match_type_expr.quote_with(smart_quote!(Vars { all_tags }, {
|
||||
return Err(serde::de::Error::unknown_variant(&ty.ty, &[all_tags]));
|
||||
}));
|
||||
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
match_type_expr,
|
||||
Enum: &ident
|
||||
},
|
||||
{
|
||||
impl<'de> serde::Deserialize<'de> for Enum {
|
||||
fn deserialize<D>(Deserializer: D) -> ::std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let content =
|
||||
<serde::private::de::Content as serde::Deserialize>::deserialize(
|
||||
Deserializer,
|
||||
)?;
|
||||
|
||||
let ty = swc_common::serializer::Type::deserialize(
|
||||
serde::private::de::ContentRefDeserializer::<D::Error>::new(
|
||||
&content,
|
||||
),
|
||||
)?;
|
||||
|
||||
match_type_expr
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(generics.clone())
|
||||
};
|
||||
|
||||
vec![deserialize]
|
||||
}
|
||||
|
||||
pub fn expand_struct(args: Args, i: DeriveInput) -> Vec<ItemImpl> {
|
||||
let mut items = vec![];
|
||||
let generics = i.generics.clone();
|
||||
let item_ident = Ident::new("Item", i.ident.span());
|
||||
|
@ -82,6 +82,21 @@ pub fn derive_from_variant(input: proc_macro::TokenStream) -> proc_macro::TokenS
|
||||
print("derive(FromVariant)", item.dump())
|
||||
}
|
||||
|
||||
#[proc_macro_derive(DeserializeEnum, attributes(tag))]
|
||||
pub fn derive_deserialize_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse::<DeriveInput>(input).expect("failed to parse input as DeriveInput");
|
||||
|
||||
let item =
|
||||
ast_node_macro::expand_enum(input)
|
||||
.into_iter()
|
||||
.fold(TokenStream::new(), |mut t, item| {
|
||||
item.to_tokens(&mut t);
|
||||
t
|
||||
});
|
||||
|
||||
print("derive(DeserializeEnum)", item.dump())
|
||||
}
|
||||
|
||||
/// Alias for
|
||||
/// `#[derive(Spanned, Fold, Clone, Debug, PartialEq)]` for a struct and
|
||||
/// `#[derive(Spanned, Fold, Clone, Debug, PartialEq, FromVariant)]` for an
|
||||
@ -100,9 +115,10 @@ pub fn ast_node(
|
||||
if !args.is_empty() {
|
||||
panic!("#[ast_node] on enum does not accept any argument")
|
||||
}
|
||||
|
||||
item.quote_with(smart_quote!(Vars { input }, {
|
||||
#[derive(::swc_common::FromVariant, ::swc_common::Spanned, Clone, Debug, PartialEq)]
|
||||
#[derive(::serde::Serialize, ::serde::Deserialize)]
|
||||
#[derive(::serde::Serialize, ::swc_common::DeserializeEnum)]
|
||||
#[serde(untagged)]
|
||||
#[cfg_attr(feature = "fold", derive(::swc_common::Fold))]
|
||||
input
|
||||
@ -138,7 +154,7 @@ pub fn ast_node(
|
||||
});
|
||||
|
||||
let ast_node_impl = match args {
|
||||
Some(ref args) => Some(ast_node_macro::expand(args.clone(), input.clone())),
|
||||
Some(ref args) => Some(ast_node_macro::expand_struct(args.clone(), input.clone())),
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
use swc_common::{ast_node, Fold, Span, Spanned};
|
||||
|
||||
#[ast_node]
|
||||
#[derive(Deserialize)]
|
||||
// See https://github.com/rust-lang/rust/issues/44925
|
||||
pub struct Class {
|
||||
#[span]
|
||||
@ -14,9 +15,18 @@ pub struct Class {
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Tuple(#[span] HasSpan, #[fold(ignore)] usize, usize);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Fold, Spanned, Serialize, Deserialize)]
|
||||
pub struct HasSpan {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[ast_node]
|
||||
pub enum Node {
|
||||
#[tag("Class")]
|
||||
Class(Class),
|
||||
#[tag("Tuple")]
|
||||
Tuple(Tuple),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user