mirror of
https://github.com/swc-project/swc.git
synced 2024-12-30 00:52:29 +03:00
9dd0647e3a
swc_ecma_ast: - Improve API for AST creation.
1049 lines
24 KiB
Rust
1049 lines
24 KiB
Rust
#![allow(clippy::vec_box)]
|
|
use crate::{
|
|
class::Class,
|
|
function::Function,
|
|
ident::{Ident, PrivateName},
|
|
jsx::{JSXElement, JSXEmptyExpr, JSXFragment, JSXMemberExpr, JSXNamespacedName},
|
|
lit::{Lit, Str},
|
|
operators::{AssignOp, BinaryOp, UnaryOp, UpdateOp},
|
|
pat::Pat,
|
|
prop::Prop,
|
|
stmt::BlockStmt,
|
|
typescript::{
|
|
TsAsExpr, TsConstAssertion, TsNonNullExpr, TsTypeAnn, TsTypeAssertion, TsTypeParamDecl,
|
|
TsTypeParamInstantiation,
|
|
},
|
|
ComputedPropName, Invalid,
|
|
};
|
|
use is_macro::Is;
|
|
use serde::{self, Deserialize, Serialize};
|
|
use string_enum::StringEnum;
|
|
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, Spanned, DUMMY_SP};
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum Expr {
|
|
#[tag("ThisExpression")]
|
|
This(ThisExpr),
|
|
|
|
#[tag("ArrayExpression")]
|
|
Array(ArrayLit),
|
|
|
|
#[tag("ObjectExpression")]
|
|
Object(ObjectLit),
|
|
|
|
#[tag("FunctionExpression")]
|
|
#[is(name = "fn_expr")]
|
|
Fn(FnExpr),
|
|
|
|
#[tag("UnaryExpression")]
|
|
Unary(UnaryExpr),
|
|
|
|
/// `++v`, `--v`, `v++`, `v--`
|
|
#[tag("UpdateExpression")]
|
|
Update(UpdateExpr),
|
|
|
|
#[tag("BinaryExpression")]
|
|
Bin(BinExpr),
|
|
|
|
#[tag("AssignmentExpression")]
|
|
Assign(AssignExpr),
|
|
|
|
//
|
|
// Logical {
|
|
//
|
|
// op: LogicalOp,
|
|
// left: Box<Expr>,
|
|
// right: Box<Expr>,
|
|
// },
|
|
/// 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.
|
|
#[tag("MemberExpression")]
|
|
Member(MemberExpr),
|
|
|
|
#[tag("SuperPropExpression")]
|
|
SuperProp(SuperPropExpr),
|
|
|
|
/// 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")]
|
|
#[tag("BigIntLiteral")]
|
|
Lit(Lit),
|
|
|
|
#[tag("TemplateLiteral")]
|
|
Tpl(Tpl),
|
|
|
|
#[tag("TaggedTemplateExpression")]
|
|
TaggedTpl(TaggedTpl),
|
|
|
|
#[tag("ArrowFunctionExpression")]
|
|
Arrow(ArrowExpr),
|
|
|
|
#[tag("ClassExpression")]
|
|
Class(ClassExpr),
|
|
|
|
#[tag("YieldExpression")]
|
|
#[is(name = "yield_expr")]
|
|
Yield(YieldExpr),
|
|
|
|
#[tag("MetaProperty")]
|
|
MetaProp(MetaPropExpr),
|
|
|
|
#[tag("AwaitExpression")]
|
|
#[is(name = "await_expr")]
|
|
Await(AwaitExpr),
|
|
|
|
#[tag("ParenthesisExpression")]
|
|
Paren(ParenExpr),
|
|
|
|
#[tag("JSXMemberExpression")]
|
|
JSXMember(JSXMemberExpr),
|
|
|
|
#[tag("JSXNamespacedName")]
|
|
JSXNamespacedName(JSXNamespacedName),
|
|
|
|
#[tag("JSXEmptyExpression")]
|
|
JSXEmpty(JSXEmptyExpr),
|
|
|
|
#[tag("JSXElement")]
|
|
JSXElement(Box<JSXElement>),
|
|
|
|
#[tag("JSXFragment")]
|
|
JSXFragment(JSXFragment),
|
|
|
|
#[tag("TsTypeAssertion")]
|
|
TsTypeAssertion(TsTypeAssertion),
|
|
|
|
#[tag("TsConstAssertion")]
|
|
TsConstAssertion(TsConstAssertion),
|
|
|
|
#[tag("TsNonNullExpression")]
|
|
TsNonNull(TsNonNullExpr),
|
|
|
|
#[tag("TsAsExpression")]
|
|
TsAs(TsAsExpr),
|
|
|
|
#[tag("PrivateName")]
|
|
PrivateName(PrivateName),
|
|
|
|
#[tag("OptionalChainingExpression")]
|
|
OptChain(OptChainExpr),
|
|
|
|
#[tag("Invalid")]
|
|
Invalid(Invalid),
|
|
}
|
|
|
|
impl Take for Expr {
|
|
fn dummy() -> Self {
|
|
Expr::Invalid(Invalid { span: DUMMY_SP })
|
|
}
|
|
}
|
|
|
|
#[ast_node("ThisExpression")]
|
|
#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ThisExpr {
|
|
pub span: Span,
|
|
}
|
|
|
|
/// Array literal.
|
|
#[ast_node("ArrayExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ArrayLit {
|
|
pub span: Span,
|
|
|
|
#[serde(default, rename = "elements")]
|
|
pub elems: Vec<Option<ExprOrSpread>>,
|
|
}
|
|
|
|
impl Take for ArrayLit {
|
|
fn dummy() -> Self {
|
|
ArrayLit {
|
|
span: DUMMY_SP,
|
|
elems: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Object literal.
|
|
#[ast_node("ObjectExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ObjectLit {
|
|
pub span: Span,
|
|
|
|
#[serde(default, rename = "properties")]
|
|
pub props: Vec<PropOrSpread>,
|
|
}
|
|
|
|
impl Take for ObjectLit {
|
|
fn dummy() -> Self {
|
|
ObjectLit {
|
|
span: DUMMY_SP,
|
|
props: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum PropOrSpread {
|
|
/// Spread properties, e.g., `{a: 1, ...obj, b: 2}`.
|
|
#[tag("SpreadElement")]
|
|
Spread(SpreadElement),
|
|
|
|
#[tag("*")]
|
|
Prop(Box<Prop>),
|
|
}
|
|
|
|
#[ast_node("SpreadElement")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct SpreadElement {
|
|
#[serde(rename = "spread")]
|
|
#[span(lo)]
|
|
pub dot3_token: Span,
|
|
|
|
#[serde(rename = "arguments")]
|
|
#[span(hi)]
|
|
pub expr: Box<Expr>,
|
|
}
|
|
|
|
impl Take for SpreadElement {
|
|
fn dummy() -> Self {
|
|
SpreadElement {
|
|
dot3_token: DUMMY_SP,
|
|
expr: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("UnaryExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct UnaryExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "operator")]
|
|
pub op: UnaryOp,
|
|
|
|
#[serde(rename = "argument")]
|
|
pub arg: Box<Expr>,
|
|
}
|
|
|
|
impl Take for UnaryExpr {
|
|
fn dummy() -> Self {
|
|
UnaryExpr {
|
|
span: DUMMY_SP,
|
|
op: op!("!"),
|
|
arg: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("UpdateExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct UpdateExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "operator")]
|
|
pub op: UpdateOp,
|
|
|
|
pub prefix: bool,
|
|
|
|
#[serde(rename = "argument")]
|
|
pub arg: Box<Expr>,
|
|
}
|
|
|
|
impl Take for UpdateExpr {
|
|
fn dummy() -> Self {
|
|
UpdateExpr {
|
|
span: DUMMY_SP,
|
|
op: op!("++"),
|
|
prefix: false,
|
|
arg: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("BinaryExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct BinExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "operator")]
|
|
pub op: BinaryOp,
|
|
|
|
pub left: Box<Expr>,
|
|
|
|
pub right: Box<Expr>,
|
|
}
|
|
|
|
impl Take for BinExpr {
|
|
fn dummy() -> Self {
|
|
BinExpr {
|
|
span: DUMMY_SP,
|
|
op: op!("*"),
|
|
left: Take::dummy(),
|
|
right: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Function expression.
|
|
#[ast_node("FunctionExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct FnExpr {
|
|
#[serde(default, rename = "identifier")]
|
|
pub ident: Option<Ident>,
|
|
|
|
#[serde(flatten)]
|
|
#[span]
|
|
pub function: Function,
|
|
}
|
|
|
|
impl Take for FnExpr {
|
|
fn dummy() -> Self {
|
|
FnExpr {
|
|
ident: None,
|
|
function: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Class expression.
|
|
#[ast_node("ClassExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ClassExpr {
|
|
#[serde(default, rename = "identifier")]
|
|
pub ident: Option<Ident>,
|
|
|
|
#[serde(flatten)]
|
|
#[span]
|
|
pub class: Class,
|
|
}
|
|
|
|
impl Take for ClassExpr {
|
|
fn dummy() -> Self {
|
|
ClassExpr {
|
|
ident: None,
|
|
class: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
#[ast_node("AssignmentExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct AssignExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "operator")]
|
|
pub op: AssignOp,
|
|
|
|
pub left: PatOrExpr,
|
|
|
|
pub right: Box<Expr>,
|
|
}
|
|
|
|
impl Take for AssignExpr {
|
|
fn dummy() -> Self {
|
|
AssignExpr {
|
|
span: DUMMY_SP,
|
|
op: op!("="),
|
|
left: Take::dummy(),
|
|
right: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("MemberExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct MemberExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "object")]
|
|
pub obj: Box<Expr>,
|
|
|
|
#[serde(rename = "property")]
|
|
pub prop: MemberProp,
|
|
}
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum MemberProp {
|
|
#[tag("Identifier")]
|
|
Ident(Ident),
|
|
#[tag("PrivateName")]
|
|
PrivateName(PrivateName),
|
|
#[tag("Computed")]
|
|
Computed(ComputedPropName),
|
|
}
|
|
|
|
#[ast_node("SuperPropExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct SuperPropExpr {
|
|
pub span: Span,
|
|
|
|
pub obj: Super,
|
|
|
|
#[serde(rename = "property")]
|
|
pub prop: SuperProp,
|
|
}
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum SuperProp {
|
|
#[tag("Identifier")]
|
|
Ident(Ident),
|
|
#[tag("Computed")]
|
|
Computed(ComputedPropName),
|
|
}
|
|
|
|
impl Take for MemberExpr {
|
|
fn dummy() -> Self {
|
|
MemberExpr {
|
|
span: DUMMY_SP,
|
|
obj: Take::dummy(),
|
|
prop: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Take for MemberProp {
|
|
fn dummy() -> Self {
|
|
MemberProp::Ident(Ident::dummy())
|
|
}
|
|
}
|
|
|
|
impl Take for SuperProp {
|
|
fn dummy() -> Self {
|
|
SuperProp::Ident(Ident::dummy())
|
|
}
|
|
}
|
|
|
|
#[ast_node("ConditionalExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct CondExpr {
|
|
pub span: Span,
|
|
|
|
pub test: Box<Expr>,
|
|
|
|
#[serde(rename = "consequent")]
|
|
pub cons: Box<Expr>,
|
|
|
|
#[serde(rename = "alternate")]
|
|
pub alt: Box<Expr>,
|
|
}
|
|
|
|
impl Take for CondExpr {
|
|
fn dummy() -> Self {
|
|
CondExpr {
|
|
span: DUMMY_SP,
|
|
test: Take::dummy(),
|
|
cons: Take::dummy(),
|
|
alt: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("CallExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct CallExpr {
|
|
pub span: Span,
|
|
|
|
pub callee: Callee,
|
|
|
|
#[serde(default, rename = "arguments")]
|
|
pub args: Vec<ExprOrSpread>,
|
|
|
|
#[serde(default, rename = "typeArguments")]
|
|
pub type_args: Option<TsTypeParamInstantiation>,
|
|
// pub type_params: Option<TsTypeParamInstantiation>,
|
|
}
|
|
|
|
impl Take for CallExpr {
|
|
fn dummy() -> Self {
|
|
CallExpr {
|
|
span: DUMMY_SP,
|
|
callee: Take::dummy(),
|
|
args: Take::dummy(),
|
|
type_args: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("NewExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct NewExpr {
|
|
pub span: Span,
|
|
|
|
pub callee: Box<Expr>,
|
|
|
|
#[serde(default, rename = "arguments")]
|
|
pub args: Option<Vec<ExprOrSpread>>,
|
|
|
|
#[serde(default, rename = "typeArguments")]
|
|
pub type_args: Option<TsTypeParamInstantiation>,
|
|
// pub type_params: Option<TsTypeParamInstantiation>,
|
|
}
|
|
|
|
impl Take for NewExpr {
|
|
fn dummy() -> Self {
|
|
NewExpr {
|
|
span: DUMMY_SP,
|
|
callee: Take::dummy(),
|
|
args: Take::dummy(),
|
|
type_args: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("SequenceExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct SeqExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "expressions")]
|
|
pub exprs: Vec<Box<Expr>>,
|
|
}
|
|
|
|
impl Take for SeqExpr {
|
|
fn dummy() -> Self {
|
|
SeqExpr {
|
|
span: DUMMY_SP,
|
|
exprs: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("ArrowFunctionExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ArrowExpr {
|
|
pub span: Span,
|
|
|
|
pub params: Vec<Pat>,
|
|
|
|
pub body: BlockStmtOrExpr,
|
|
|
|
#[serde(default, rename = "async")]
|
|
pub is_async: bool,
|
|
|
|
#[serde(default, rename = "generator")]
|
|
pub is_generator: bool,
|
|
|
|
#[serde(default, rename = "typeParameters")]
|
|
pub type_params: Option<TsTypeParamDecl>,
|
|
|
|
#[serde(default)]
|
|
pub return_type: Option<TsTypeAnn>,
|
|
}
|
|
|
|
impl Take for ArrowExpr {
|
|
fn dummy() -> Self {
|
|
ArrowExpr {
|
|
span: DUMMY_SP,
|
|
params: Take::dummy(),
|
|
body: Take::dummy(),
|
|
is_async: false,
|
|
is_generator: false,
|
|
type_params: Take::dummy(),
|
|
return_type: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("YieldExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct YieldExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(default, rename = "argument")]
|
|
pub arg: Option<Box<Expr>>,
|
|
|
|
#[serde(default)]
|
|
pub delegate: bool,
|
|
}
|
|
|
|
impl Take for YieldExpr {
|
|
fn dummy() -> Self {
|
|
YieldExpr {
|
|
span: DUMMY_SP,
|
|
arg: Take::dummy(),
|
|
delegate: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("MetaProperty")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan, Copy)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct MetaPropExpr {
|
|
pub span: Span,
|
|
pub kind: MetaPropKind,
|
|
}
|
|
|
|
#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
#[cfg_attr(
|
|
feature = "rkyv",
|
|
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
|
|
)]
|
|
pub enum MetaPropKind {
|
|
/// `new.target`
|
|
NewTarget,
|
|
/// `import.meta`
|
|
ImportMeta,
|
|
}
|
|
|
|
#[ast_node("AwaitExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct AwaitExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "argument")]
|
|
pub arg: Box<Expr>,
|
|
}
|
|
|
|
#[ast_node("TemplateLiteral")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct Tpl {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "expressions")]
|
|
pub exprs: Vec<Box<Expr>>,
|
|
|
|
pub quasis: Vec<TplElement>,
|
|
}
|
|
|
|
impl Take for Tpl {
|
|
fn dummy() -> Self {
|
|
Tpl {
|
|
span: DUMMY_SP,
|
|
exprs: Take::dummy(),
|
|
quasis: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("TaggedTemplateExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct TaggedTpl {
|
|
pub span: Span,
|
|
|
|
pub tag: Box<Expr>,
|
|
|
|
#[serde(default, rename = "typeParameters")]
|
|
pub type_params: Option<TsTypeParamInstantiation>,
|
|
|
|
#[serde(rename = "template")]
|
|
pub tpl: Tpl,
|
|
}
|
|
|
|
impl Take for TaggedTpl {
|
|
fn dummy() -> Self {
|
|
TaggedTpl {
|
|
span: DUMMY_SP,
|
|
tag: Take::dummy(),
|
|
type_params: Take::dummy(),
|
|
tpl: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("TemplateElement")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct TplElement {
|
|
pub span: Span,
|
|
pub tail: bool,
|
|
|
|
/// This value is never used by `swc_ecma_codegen`, and this fact is
|
|
/// considered as a public API.
|
|
///
|
|
/// If you are going to use codegen right after creating a [TplElement], you
|
|
/// don't have to worry about this value.
|
|
pub cooked: Option<Str>,
|
|
pub raw: Str,
|
|
}
|
|
|
|
impl Take for TplElement {
|
|
fn dummy() -> Self {
|
|
TplElement {
|
|
span: DUMMY_SP,
|
|
tail: Default::default(),
|
|
cooked: Take::dummy(),
|
|
raw: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node("ParenthesisExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct ParenExpr {
|
|
pub span: Span,
|
|
|
|
#[serde(rename = "expression")]
|
|
pub expr: Box<Expr>,
|
|
}
|
|
impl Take for ParenExpr {
|
|
fn dummy() -> Self {
|
|
ParenExpr {
|
|
span: DUMMY_SP,
|
|
expr: Take::dummy(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node]
|
|
#[allow(variant_size_differences)]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum Callee {
|
|
#[tag("Super")]
|
|
#[is(name = "super_")]
|
|
Super(Super),
|
|
|
|
#[tag("Import")]
|
|
Import(Import),
|
|
|
|
#[tag("*")]
|
|
Expr(Box<Expr>),
|
|
}
|
|
|
|
impl Take for Callee {
|
|
fn dummy() -> Self {
|
|
Callee::Super(Take::dummy())
|
|
}
|
|
}
|
|
|
|
#[ast_node("Super")]
|
|
#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct Super {
|
|
pub span: Span,
|
|
}
|
|
|
|
impl Take for Super {
|
|
fn dummy() -> Self {
|
|
Super { span: DUMMY_SP }
|
|
}
|
|
}
|
|
|
|
#[ast_node("Import")]
|
|
#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct Import {
|
|
pub span: Span,
|
|
}
|
|
|
|
impl Take for Import {
|
|
fn dummy() -> Self {
|
|
Import { span: DUMMY_SP }
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
#[cfg_attr(
|
|
feature = "rkyv",
|
|
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
|
|
)]
|
|
#[cfg_attr(
|
|
feature = "rkyv",
|
|
archive(bound(serialize = "__S: rkyv::ser::Serializer + rkyv::ser::ScratchSpace"))
|
|
)]
|
|
pub struct ExprOrSpread {
|
|
#[serde(default)]
|
|
#[cfg_attr(feature = "rkyv", omit_bounds)]
|
|
pub spread: Option<Span>,
|
|
|
|
#[serde(rename = "expression")]
|
|
#[cfg_attr(feature = "rkyv", omit_bounds)]
|
|
pub expr: Box<Expr>,
|
|
}
|
|
|
|
impl Spanned for ExprOrSpread {
|
|
fn span(&self) -> Span {
|
|
let expr = self.expr.span();
|
|
match self.spread {
|
|
Some(spread) => expr.with_lo(spread.lo()),
|
|
None => expr,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
|
#[allow(variant_size_differences)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum BlockStmtOrExpr {
|
|
#[tag("BlockStatement")]
|
|
BlockStmt(BlockStmt),
|
|
#[tag("*")]
|
|
Expr(Box<Expr>),
|
|
}
|
|
|
|
impl Take for BlockStmtOrExpr {
|
|
fn dummy() -> Self {
|
|
BlockStmtOrExpr::Expr(Take::dummy())
|
|
}
|
|
}
|
|
|
|
#[ast_node]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub enum PatOrExpr {
|
|
#[tag("ThisExpression")]
|
|
#[tag("ArrayExpression")]
|
|
#[tag("ObjectExpression")]
|
|
#[tag("FunctionExpression")]
|
|
#[tag("UnaryExpression")]
|
|
#[tag("UpdateExpression")]
|
|
#[tag("BinaryExpression")]
|
|
#[tag("AssignmentExpression")]
|
|
#[tag("MemberExpression")]
|
|
#[tag("SuperPropExpression")]
|
|
#[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("TsConstAssertion")]
|
|
#[tag("TsNonNullExpression")]
|
|
#[tag("TsAsExpression")]
|
|
#[tag("PrivateName")]
|
|
Expr(Box<Expr>),
|
|
#[tag("*")]
|
|
Pat(Box<Pat>),
|
|
}
|
|
|
|
impl PatOrExpr {
|
|
/// Returns the [Pat] if this is a pattern, otherwise returns [None].
|
|
pub fn pat(self) -> Option<Box<Pat>> {
|
|
match self {
|
|
PatOrExpr::Expr(_) => None,
|
|
PatOrExpr::Pat(p) => Some(p),
|
|
}
|
|
}
|
|
|
|
/// Returns the [Expr] if this is an expression, otherwise returns
|
|
/// `None`.
|
|
pub fn expr(self) -> Option<Box<Expr>> {
|
|
match self {
|
|
PatOrExpr::Expr(e) => Some(e),
|
|
PatOrExpr::Pat(p) => match *p {
|
|
Pat::Expr(e) => Some(e),
|
|
_ => None,
|
|
},
|
|
}
|
|
}
|
|
|
|
#[track_caller]
|
|
pub fn expect_pat(self) -> Box<Pat> {
|
|
self.pat()
|
|
.expect("expect_pat is called but it was not a pattern")
|
|
}
|
|
|
|
#[track_caller]
|
|
pub fn expect_expr(self) -> Box<Expr> {
|
|
self.expr()
|
|
.expect("expect_expr is called but it was not a pattern")
|
|
}
|
|
|
|
pub fn as_pat(&self) -> Option<&Pat> {
|
|
match self {
|
|
PatOrExpr::Expr(_) => None,
|
|
PatOrExpr::Pat(p) => Some(p),
|
|
}
|
|
}
|
|
|
|
pub fn as_expr(&self) -> Option<&Expr> {
|
|
match self {
|
|
PatOrExpr::Expr(e) => Some(e),
|
|
PatOrExpr::Pat(p) => match &**p {
|
|
Pat::Expr(e) => Some(e),
|
|
_ => None,
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn is_pat(&self) -> bool {
|
|
self.as_pat().is_some()
|
|
}
|
|
|
|
pub fn is_expr(&self) -> bool {
|
|
self.as_expr().is_some()
|
|
}
|
|
|
|
pub fn as_ident(&self) -> Option<&Ident> {
|
|
match self {
|
|
PatOrExpr::Expr(v) => match &**v {
|
|
Expr::Ident(i) => Some(i),
|
|
_ => None,
|
|
},
|
|
PatOrExpr::Pat(v) => match &**v {
|
|
Pat::Ident(i) => Some(&i.id),
|
|
Pat::Expr(v) => match &**v {
|
|
Expr::Ident(i) => Some(i),
|
|
_ => None,
|
|
},
|
|
_ => None,
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn as_ident_mut(&mut self) -> Option<&mut Ident> {
|
|
match self {
|
|
PatOrExpr::Expr(v) => match &mut **v {
|
|
Expr::Ident(i) => Some(i),
|
|
_ => None,
|
|
},
|
|
PatOrExpr::Pat(v) => match &mut **v {
|
|
Pat::Ident(i) => Some(&mut i.id),
|
|
Pat::Expr(v) => match &mut **v {
|
|
Expr::Ident(i) => Some(i),
|
|
_ => None,
|
|
},
|
|
_ => None,
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn normalize_expr(self) -> Self {
|
|
match self {
|
|
PatOrExpr::Pat(pat) => match *pat {
|
|
Pat::Expr(expr) => PatOrExpr::Expr(expr),
|
|
_ => PatOrExpr::Pat(pat),
|
|
},
|
|
_ => self,
|
|
}
|
|
}
|
|
|
|
pub fn normalize_ident(self) -> Self {
|
|
match self {
|
|
PatOrExpr::Expr(expr) => match *expr {
|
|
Expr::Ident(i) => PatOrExpr::Pat(Box::new(Pat::Ident(i.into()))),
|
|
_ => PatOrExpr::Expr(expr),
|
|
},
|
|
PatOrExpr::Pat(pat) => match *pat {
|
|
Pat::Expr(expr) => match *expr {
|
|
Expr::Ident(i) => PatOrExpr::Pat(Box::new(Pat::Ident(i.into()))),
|
|
_ => PatOrExpr::Expr(expr),
|
|
},
|
|
_ => PatOrExpr::Pat(pat),
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Take for PatOrExpr {
|
|
fn dummy() -> Self {
|
|
PatOrExpr::Pat(Take::dummy())
|
|
}
|
|
}
|
|
|
|
#[ast_node("OptionalChainingExpression")]
|
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
|
pub struct OptChainExpr {
|
|
pub span: Span,
|
|
pub question_dot_token: Span,
|
|
pub expr: Box<Expr>,
|
|
}
|
|
|
|
test_de!(
|
|
jsx_element,
|
|
JSXElement,
|
|
r#"{
|
|
"type": "JSXElement",
|
|
"span": {
|
|
"start": 0,
|
|
"end": 5,
|
|
"ctxt": 0
|
|
},
|
|
"opening": {
|
|
"type": "JSXOpeningElement",
|
|
"name": {
|
|
"type": "Identifier",
|
|
"span": {
|
|
"start": 1,
|
|
"end": 2,
|
|
"ctxt": 0
|
|
},
|
|
"value": "a",
|
|
"optional": false
|
|
},
|
|
"span": {
|
|
"start": 1,
|
|
"end": 5,
|
|
"ctxt": 0
|
|
},
|
|
"selfClosing": true
|
|
},
|
|
"children": [],
|
|
"closing": null
|
|
}"#
|
|
);
|