swc_ecma_ast/
decl.rs

1use is_macro::Is;
2use string_enum::StringEnum;
3use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, SyntaxContext, DUMMY_SP};
4
5use crate::{
6    class::Class,
7    expr::Expr,
8    function::Function,
9    ident::Ident,
10    pat::Pat,
11    typescript::{TsEnumDecl, TsInterfaceDecl, TsModuleDecl, TsTypeAliasDecl},
12};
13
14#[ast_node]
15#[derive(Eq, Hash, Is, EqIgnoreSpan)]
16#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
17#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
18pub enum Decl {
19    #[tag("ClassDeclaration")]
20    Class(ClassDecl),
21    #[tag("FunctionDeclaration")]
22    #[is(name = "fn_decl")]
23    Fn(FnDecl),
24    #[tag("VariableDeclaration")]
25    Var(Box<VarDecl>),
26    #[tag("UsingDeclaration")]
27    Using(Box<UsingDecl>),
28
29    #[tag("TsInterfaceDeclaration")]
30    TsInterface(Box<TsInterfaceDecl>),
31    #[tag("TsTypeAliasDeclaration")]
32    TsTypeAlias(Box<TsTypeAliasDecl>),
33    #[tag("TsEnumDeclaration")]
34    TsEnum(Box<TsEnumDecl>),
35    #[tag("TsModuleDeclaration")]
36    TsModule(Box<TsModuleDecl>),
37}
38
39boxed!(
40    Decl,
41    [
42        VarDecl,
43        UsingDecl,
44        TsInterfaceDecl,
45        TsTypeAliasDecl,
46        TsEnumDecl,
47        TsModuleDecl
48    ]
49);
50
51macro_rules! decl_from {
52    ($($variant_ty:ty),*) => {
53        $(
54            bridge_from!(crate::Stmt, Decl, $variant_ty);
55            bridge_from!(crate::ModuleItem, crate::Stmt, $variant_ty);
56        )*
57    };
58}
59
60decl_from!(
61    ClassDecl,
62    FnDecl,
63    VarDecl,
64    UsingDecl,
65    TsInterfaceDecl,
66    TsTypeAliasDecl,
67    TsEnumDecl,
68    TsModuleDecl
69);
70
71macro_rules! decl_from_boxed {
72    ($($variant_ty:ty),*) => {
73        $(
74            bridge_from!(Box<crate::Stmt>, Decl, $variant_ty);
75            bridge_from!(Box<crate::Stmt>, Decl, Box<$variant_ty>);
76            bridge_from!(crate::Stmt, Decl, Box<$variant_ty>);
77            bridge_from!(crate::ModuleItem, crate::Stmt, Box<$variant_ty>);
78        )*
79    };
80}
81
82decl_from_boxed!(
83    VarDecl,
84    UsingDecl,
85    TsInterfaceDecl,
86    TsTypeAliasDecl,
87    TsEnumDecl,
88    TsModuleDecl
89);
90
91impl Take for Decl {
92    fn dummy() -> Self {
93        Decl::Var(Default::default())
94    }
95}
96
97#[ast_node("FunctionDeclaration")]
98#[derive(Eq, Hash, EqIgnoreSpan)]
99#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
100#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
101pub struct FnDecl {
102    #[cfg_attr(feature = "serde-impl", serde(rename = "identifier"))]
103    pub ident: Ident,
104
105    #[cfg_attr(feature = "serde-impl", serde(default))]
106    pub declare: bool,
107
108    #[cfg_attr(feature = "serde-impl", serde(flatten))]
109    #[span]
110    pub function: Box<Function>,
111}
112
113impl Take for FnDecl {
114    fn dummy() -> Self {
115        FnDecl {
116            ident: Take::dummy(),
117            declare: Default::default(),
118            function: Take::dummy(),
119        }
120    }
121}
122
123#[ast_node("ClassDeclaration")]
124#[derive(Eq, Hash, EqIgnoreSpan)]
125#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
126#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
127pub struct ClassDecl {
128    #[cfg_attr(feature = "serde-impl", serde(rename = "identifier"))]
129    pub ident: Ident,
130
131    #[cfg_attr(feature = "serde-impl", serde(default))]
132    pub declare: bool,
133
134    #[cfg_attr(feature = "serde-impl", serde(flatten))]
135    #[span]
136    pub class: Box<Class>,
137}
138
139impl Take for ClassDecl {
140    fn dummy() -> Self {
141        ClassDecl {
142            ident: Take::dummy(),
143            declare: Default::default(),
144            class: Take::dummy(),
145        }
146    }
147}
148
149#[ast_node("VariableDeclaration")]
150#[derive(Eq, Hash, EqIgnoreSpan, Default)]
151#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
152#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
153pub struct VarDecl {
154    pub span: Span,
155
156    pub ctxt: SyntaxContext,
157
158    pub kind: VarDeclKind,
159
160    #[cfg_attr(feature = "serde-impl", serde(default))]
161    pub declare: bool,
162
163    #[cfg_attr(feature = "serde-impl", serde(rename = "declarations"))]
164    pub decls: Vec<VarDeclarator>,
165}
166
167impl Take for VarDecl {
168    fn dummy() -> Self {
169        Default::default()
170    }
171}
172
173#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan, Default)]
174#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
175#[cfg_attr(
176    any(feature = "rkyv-impl"),
177    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
178)]
179#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
180#[cfg_attr(feature = "rkyv-impl", repr(u32))]
181#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
182pub enum VarDeclKind {
183    /// `var`
184    #[default]
185    Var,
186    /// `let`
187    Let,
188    /// `const`
189    Const,
190}
191
192#[ast_node("VariableDeclarator")]
193#[derive(Eq, Hash, EqIgnoreSpan)]
194#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
195#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
196pub struct VarDeclarator {
197    pub span: Span,
198    #[cfg_attr(feature = "serde-impl", serde(rename = "id"))]
199    pub name: Pat,
200
201    /// Initialization expression.
202    #[cfg_attr(feature = "serde-impl", serde(default))]
203    pub init: Option<Box<Expr>>,
204
205    /// Typescript only
206    #[cfg_attr(feature = "serde-impl", serde(default))]
207    pub definite: bool,
208}
209
210impl Take for VarDeclarator {
211    fn dummy() -> Self {
212        VarDeclarator {
213            span: DUMMY_SP,
214            name: Take::dummy(),
215            init: Take::dummy(),
216            definite: Default::default(),
217        }
218    }
219}
220
221#[ast_node("UsingDeclaration")]
222#[derive(Eq, Hash, EqIgnoreSpan)]
223#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
224#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
225pub struct UsingDecl {
226    #[cfg_attr(feature = "serde-impl", serde(default))]
227    pub span: Span,
228
229    #[cfg_attr(feature = "serde-impl", serde(default))]
230    pub is_await: bool,
231
232    #[cfg_attr(feature = "serde-impl", serde(default))]
233    pub decls: Vec<VarDeclarator>,
234}
235
236impl Take for UsingDecl {
237    fn dummy() -> Self {
238        Self {
239            span: DUMMY_SP,
240            is_await: Default::default(),
241            decls: Take::dummy(),
242        }
243    }
244}