1use is_macro::Is;
2use swc_atoms::Atom;
3use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, DUMMY_SP};
4
5use crate::{module_decl::ModuleDecl, stmt::Stmt};
6
7#[ast_node]
8#[derive(Eq, Hash, Is, EqIgnoreSpan)]
9#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
10#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
11pub enum Program {
12 #[tag("Module")]
13 Module(Module),
14 #[tag("Script")]
15 Script(Script),
16}
17
18impl Take for Program {
19 fn dummy() -> Self {
20 Program::Script(Script::default())
21 }
22}
23
24#[ast_node("Module")]
25#[derive(Eq, Hash, EqIgnoreSpan, Default)]
26#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
27pub struct Module {
28 pub span: Span,
29
30 pub body: Vec<ModuleItem>,
31
32 #[cfg_attr(feature = "serde-impl", serde(default, rename = "interpreter"))]
33 pub shebang: Option<Atom>,
34}
35
36#[cfg(feature = "arbitrary")]
37#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
38impl<'a> arbitrary::Arbitrary<'a> for Module {
39 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
40 let span = u.arbitrary()?;
41 let body = u.arbitrary()?;
42 Ok(Self {
43 span,
44 body,
45 shebang: None,
46 })
47 }
48}
49
50impl Take for Module {
51 fn dummy() -> Self {
52 Module {
53 span: DUMMY_SP,
54 body: Take::dummy(),
55 shebang: Take::dummy(),
56 }
57 }
58}
59
60#[ast_node("Script")]
61#[derive(Eq, Hash, EqIgnoreSpan, Default)]
62#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
63pub struct Script {
64 pub span: Span,
65
66 pub body: Vec<Stmt>,
67
68 #[cfg_attr(feature = "serde-impl", serde(default, rename = "interpreter"))]
69 pub shebang: Option<Atom>,
70}
71
72#[cfg(feature = "arbitrary")]
73#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
74impl<'a> arbitrary::Arbitrary<'a> for Script {
75 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
76 let span = u.arbitrary()?;
77 let body = u.arbitrary()?;
78 Ok(Self {
79 span,
80 body,
81 shebang: None,
82 })
83 }
84}
85
86impl Take for Script {
87 fn dummy() -> Self {
88 Script {
89 span: DUMMY_SP,
90 body: Take::dummy(),
91 shebang: Take::dummy(),
92 }
93 }
94}
95
96#[ast_node]
97#[derive(Eq, Hash, Is, EqIgnoreSpan)]
98#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
99#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
100pub enum ModuleItem {
101 #[tag("ImportDeclaration")]
102 #[tag("ExportDeclaration")]
103 #[tag("ExportNamedDeclaration")]
104 #[tag("ExportDefaultDeclaration")]
105 #[tag("ExportDefaultExpression")]
106 #[tag("ExportAllDeclaration")]
107 #[tag("TsImportEqualsDeclaration")]
108 #[tag("TsExportAssignment")]
109 #[tag("TsNamespaceExportDeclaration")]
110 ModuleDecl(ModuleDecl),
111 #[tag("*")]
112 Stmt(Stmt),
113}
114
115impl Take for ModuleItem {
116 fn dummy() -> Self {
117 Self::Stmt(Default::default())
118 }
119}