Skip to main content

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(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    /// `var`
183    #[default]
184    Var,
185    /// `let`
186    Let,
187    /// `const`
188    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    /// Initialization expression.
201    #[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    /// Typescript only
209    #[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}