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 #[default]
185 Var,
186 Let,
188 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 #[cfg_attr(feature = "serde-impl", serde(default))]
203 pub init: Option<Box<Expr>>,
204
205 #[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}