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(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
176#[cfg_attr(
177 feature = "encoding-impl",
178 derive(::swc_common::Encode, ::swc_common::Decode)
179)]
180#[cfg_attr(swc_ast_unknown, non_exhaustive)]
181pub enum VarDeclKind {
182 #[default]
184 Var,
185 Let,
187 Const,
189}
190
191#[ast_node("VariableDeclarator")]
192#[derive(Eq, Hash, EqIgnoreSpan)]
193#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
194#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
195pub struct VarDeclarator {
196 pub span: Span,
197 #[cfg_attr(feature = "serde-impl", serde(rename = "id"))]
198 pub name: Pat,
199
200 #[cfg_attr(feature = "serde-impl", serde(default))]
202 #[cfg_attr(
203 feature = "encoding-impl",
204 encoding(with = "cbor4ii::core::types::Maybe")
205 )]
206 pub init: Option<Box<Expr>>,
207
208 #[cfg_attr(feature = "serde-impl", serde(default))]
210 pub definite: bool,
211}
212
213impl Take for VarDeclarator {
214 fn dummy() -> Self {
215 VarDeclarator {
216 span: DUMMY_SP,
217 name: Take::dummy(),
218 init: Take::dummy(),
219 definite: Default::default(),
220 }
221 }
222}
223
224#[ast_node("UsingDeclaration")]
225#[derive(Eq, Hash, EqIgnoreSpan)]
226#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
227#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
228pub struct UsingDecl {
229 #[cfg_attr(feature = "serde-impl", serde(default))]
230 pub span: Span,
231
232 #[cfg_attr(feature = "serde-impl", serde(default))]
233 pub is_await: bool,
234
235 #[cfg_attr(feature = "serde-impl", serde(default))]
236 pub decls: Vec<VarDeclarator>,
237}
238
239impl Take for UsingDecl {
240 fn dummy() -> Self {
241 Self {
242 span: DUMMY_SP,
243 is_await: Default::default(),
244 decls: Take::dummy(),
245 }
246 }
247}