Skip to content

Commit f328e4a

Browse files
authored
refactor(ast_node): Make AST enums non_exhaustive (#11115)
**Description:** This is the split of #11100. Since we need to add unknown variants to the ast enum, this requires a lot of code changes to handle non-exhaustive matches. I'm doing this in a separate PR for review.
1 parent dfe9670 commit f328e4a

File tree

187 files changed

+2148
-109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

187 files changed

+2148
-109
lines changed

.changeset/smart-rats-smell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
ast_node: major
3+
---
4+
5+
refactor(ast): Make ast enum `non_exhaustive`

.github/workflows/CI.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ jobs:
354354
run: |
355355
./scripts/github/run-cargo-hack.sh ${{ matrix.settings.crate }}
356356
357+
- name: Check unknown variant with transforms
358+
if: matrix.settings.crate == 'swc_ecma_transforms'
359+
run: |
360+
env RUSTFLAGS="--cfg swc_ast_unknown" cargo check -p ${{ matrix.settings.crate }} --features typescript,react,proposal,optimization,module,compat
361+
357362
node-test:
358363
name: Test node bindings - ${{ matrix.os }}
359364
if: >-

crates/ast_node/src/lib.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,29 +158,34 @@ pub fn ast_node(
158158
let mut item = TokenStream::new();
159159
match input.data {
160160
Data::Enum(..) => {
161-
struct EnumArgs {
162-
clone: bool,
163-
}
164-
impl parse::Parse for EnumArgs {
165-
fn parse(i: parse::ParseStream<'_>) -> syn::Result<Self> {
166-
let name: Ident = i.parse()?;
167-
if name != "no_clone" {
168-
return Err(i.error("unknown attribute"));
169-
}
170-
Ok(EnumArgs { clone: false })
161+
use syn::parse::Parser;
162+
163+
let attrs = <syn::punctuated::Punctuated<syn::Ident, syn::Token![,]>>::parse_terminated
164+
.parse(args)
165+
.expect("failed to parse #[ast_node]");
166+
167+
let mut has_no_clone = false;
168+
let mut has_no_unknown = false;
169+
for attr in &attrs {
170+
if attr == "no_clone" {
171+
has_no_clone = true;
172+
} else if attr == "no_unknown" {
173+
has_no_unknown = true;
174+
} else {
175+
panic!("unknown attribute: {attr:?}")
171176
}
172177
}
173-
let args = if args.is_empty() {
174-
EnumArgs { clone: true }
175-
} else {
176-
parse(args).expect("failed to parse args of #[ast_node]")
177-
};
178178

179-
let clone = if args.clone {
179+
let clone = if !has_no_clone {
180180
Some(quote!(#[derive(Clone)]))
181181
} else {
182182
None
183183
};
184+
let non_exhaustive = if !has_no_unknown {
185+
Some(quote!(#[cfg_attr(swc_ast_unknown, non_exhaustive)]))
186+
} else {
187+
None
188+
};
184189

185190
item.extend(quote!(
186191
#[allow(clippy::derive_partial_eq_without_eq)]
@@ -198,6 +203,7 @@ pub fn ast_node(
198203
::swc_common::DeserializeEnum,
199204
)]
200205
#clone
206+
#non_exhaustive
201207
#[cfg_attr(
202208
feature = "rkyv-impl",
203209
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)

crates/jsdoc/src/ast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub struct TagItem {
3030
}
3131

3232
#[ast_node]
33-
#[non_exhaustive]
3433
pub enum Tag {
3534
#[tag("Yield")]
3635
Yield(YieldTag),

crates/swc_bundler/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ version = "32.0.0"
1818
[lib]
1919
bench = false
2020

21+
[lints.rust]
22+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(swc_ast_unknown)'] }
23+
2124
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
2225
[features]
2326
concurrent = ["swc_common/concurrent", "dashmap", "rayon", "indexmap/rayon"]

crates/swc_bundler/src/bundler/chunk/cjs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ fn wrap_module(
140140
unreachable!("module item found but is_es6 is false: {:?}", i)
141141
}
142142
ModuleItem::Stmt(s) => s,
143+
#[cfg(swc_ast_unknown)]
144+
_ => panic!("unable to access unknown nodes"),
143145
})
144146
.collect(),
145147
..Default::default()
@@ -318,6 +320,8 @@ where
318320
.into();
319321
return;
320322
}
323+
#[cfg(swc_ast_unknown)]
324+
_ => panic!("unable to access unknown nodes"),
321325
}
322326
}
323327

crates/swc_bundler/src/bundler/chunk/computed_key.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ where
7373
ModuleExportName::Str(..) => {
7474
unimplemented!("module string names unimplemented")
7575
}
76+
#[cfg(swc_ast_unknown)]
77+
_ => panic!("unable to access unknown nodes"),
7678
};
7779
if ctx.transitive_remap.get(&exported.ctxt).is_some() {
7880
let specifier = ExportSpecifier::Named(ExportNamedSpecifier {
@@ -230,6 +232,8 @@ impl Fold for ExportToReturn {
230232
let decl = match item {
231233
ModuleItem::ModuleDecl(decl) => decl,
232234
ModuleItem::Stmt(_) => return item,
235+
#[cfg(swc_ast_unknown)]
236+
_ => panic!("unable to access unknown nodes"),
233237
};
234238

235239
let stmt = match decl {
@@ -287,6 +291,8 @@ impl Fold for ExportToReturn {
287291
)
288292
}
289293
DefaultDecl::TsInterfaceDecl(_) => None,
294+
#[cfg(swc_ast_unknown)]
295+
_ => panic!("unable to access unknown nodes"),
290296
},
291297
ModuleDecl::ExportDefaultExpr(_) => None,
292298
ModuleDecl::ExportAll(export) => return export.into(),
@@ -308,6 +314,8 @@ impl Fold for ExportToReturn {
308314
Some(ModuleExportName::Str(..)) => {
309315
unimplemented!("module string names unimplemented")
310316
}
317+
#[cfg(swc_ast_unknown)]
318+
Some(_) => panic!("unable to access unknown nodes"),
311319
None => {
312320
if let ModuleExportName::Ident(orig) = &named.orig {
313321
self.export_id(orig.clone());
@@ -316,6 +324,8 @@ impl Fold for ExportToReturn {
316324
}
317325
}
318326
},
327+
#[cfg(swc_ast_unknown)]
328+
_ => panic!("unable to access unknown nodes"),
319329
}
320330
}
321331

@@ -332,6 +342,8 @@ impl Fold for ExportToReturn {
332342
ModuleDecl::TsImportEquals(_) => None,
333343
ModuleDecl::TsExportAssignment(_) => None,
334344
ModuleDecl::TsNamespaceExport(_) => None,
345+
#[cfg(swc_ast_unknown)]
346+
_ => panic!("unable to access unknown nodes"),
335347
};
336348

337349
if let Some(stmt) = stmt {

crates/swc_bundler/src/bundler/chunk/merge.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ where
264264
ModuleExportName::Str(..) => {
265265
unimplemented!("module string names unimplemented")
266266
}
267+
#[cfg(swc_ast_unknown)]
268+
_ => panic!("unable to access unknown nodes"),
267269
};
268270

269271
let id: Id = exported.into();
@@ -286,9 +288,13 @@ where
286288
ModuleExportName::Str(..) => {
287289
unimplemented!("module string names unimplemented")
288290
}
291+
#[cfg(swc_ast_unknown)]
292+
_ => panic!("unable to access unknown nodes"),
289293
}
290294
}
291295
}
296+
#[cfg(swc_ast_unknown)]
297+
_ => panic!("unable to access unknown nodes"),
292298
}
293299
}
294300
}
@@ -380,11 +386,15 @@ where
380386
Expr::Call(CallExpr { callee, .. }) => match callee {
381387
Callee::Super(_) | Callee::Import(_) => continue,
382388
Callee::Expr(v) => v,
389+
#[cfg(swc_ast_unknown)]
390+
_ => panic!("unable to access unknown nodes"),
383391
},
384392
Expr::Await(AwaitExpr { arg, .. }) => match &mut **arg {
385393
Expr::Call(CallExpr { callee, .. }) => match callee {
386394
Callee::Super(_) | Callee::Import(_) => continue,
387395
Callee::Expr(v) => v,
396+
#[cfg(swc_ast_unknown)]
397+
_ => panic!("unable to access unknown nodes"),
388398
},
389399
_ => continue,
390400
},
@@ -518,6 +528,8 @@ where
518528
ModuleExportName::Str(..) => {
519529
unimplemented!("module string names unimplemented")
520530
}
531+
#[cfg(swc_ast_unknown)]
532+
_ => panic!("unable to access unknown nodes"),
521533
};
522534
// Default is not exported via `export *`
523535
if &*exported.sym == "default" {
@@ -613,6 +625,8 @@ where
613625
ModuleExportName::Str(..) => {
614626
unimplemented!("module string names unimplemented")
615627
}
628+
#[cfg(swc_ast_unknown)]
629+
_ => panic!("unable to access unknown nodes"),
616630
};
617631
new.push(
618632
imported
@@ -665,6 +679,8 @@ where
665679
);
666680
}
667681
}
682+
#[cfg(swc_ast_unknown)]
683+
_ => panic!("unable to access unknown nodes"),
668684
}
669685
}
670686

@@ -754,6 +770,8 @@ where
754770
}
755771
}
756772
DefaultDecl::TsInterfaceDecl(_) => continue,
773+
#[cfg(swc_ast_unknown)]
774+
_ => panic!("unable to access unknown nodes"),
757775
}
758776

759777
// Create `export { local_default as default }`
@@ -926,6 +944,8 @@ where
926944
| Decl::TsEnum(_)
927945
| Decl::TsModule(_)
928946
| Decl::Using(..) => continue,
947+
#[cfg(swc_ast_unknown)]
948+
_ => panic!("unable to access unknown nodes"),
929949
};
930950

931951
tracing::trace!(
@@ -1023,6 +1043,8 @@ where
10231043
"module string names unimplemented"
10241044
)
10251045
}
1046+
#[cfg(swc_ast_unknown)]
1047+
_ => panic!("unable to access unknown nodes"),
10261048
};
10271049
}
10281050
ExportSpecifier::Default(s) => {
@@ -1069,6 +1091,8 @@ where
10691091
definite: Default::default(),
10701092
});
10711093
}
1094+
#[cfg(swc_ast_unknown)]
1095+
_ => panic!("unable to access unknown nodes"),
10721096
}
10731097
}
10741098

@@ -1101,6 +1125,8 @@ where
11011125
ModuleExportName::Str(..) => {
11021126
unimplemented!("module string names unimplemented")
11031127
}
1128+
#[cfg(swc_ast_unknown)]
1129+
_ => panic!("unable to access unknown nodes"),
11041130
};
11051131
let orig_ident = match orig {
11061132
ModuleExportName::Ident(ident) => ident,
@@ -1202,6 +1228,8 @@ where
12021228
ModuleExportName::Str(..) => {
12031229
unimplemented!("module string names unimplemented")
12041230
}
1231+
#[cfg(swc_ast_unknown)]
1232+
_ => panic!("unable to access unknown nodes"),
12051233
}
12061234
}
12071235
}
@@ -1262,6 +1290,8 @@ where
12621290
ModuleExportName::Str(..) => {
12631291
unimplemented!("module string names unimplemented")
12641292
}
1293+
#[cfg(swc_ast_unknown)]
1294+
_ => panic!("unable to access unknown nodes"),
12651295
};
12661296
vars.push((
12671297
module_id,
@@ -1317,6 +1347,8 @@ where
13171347
continue;
13181348
}
13191349
}
1350+
#[cfg(swc_ast_unknown)]
1351+
_ => panic!("unable to access unknown nodes"),
13201352
}
13211353
}
13221354

crates/swc_bundler/src/bundler/export.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ where
229229
ModuleExportName::Str(..) => {
230230
unimplemented!("module string names unimplemented")
231231
}
232+
#[cfg(swc_ast_unknown)]
233+
_ => panic!("unable to access unknown nodes"),
232234
};
233235
}
234236
ExportSpecifier::Default(d) => {
@@ -243,6 +245,8 @@ where
243245
ModuleExportName::Str(..) => {
244246
unimplemented!("module string names unimplemented")
245247
}
248+
#[cfg(swc_ast_unknown)]
249+
_ => panic!("unable to access unknown nodes"),
246250
};
247251
if let Some((_, export_ctxt)) = ctxt {
248252
orig.ctxt = export_ctxt;
@@ -255,6 +259,8 @@ where
255259
Some(ModuleExportName::Str(..)) => {
256260
unimplemented!("module string names unimplemented")
257261
}
262+
#[cfg(swc_ast_unknown)]
263+
Some(_) => panic!("unable to access unknown nodes"),
258264
None => {
259265
let mut exported: Ident = orig.clone();
260266
exported.ctxt = self.export_ctxt;
@@ -280,6 +286,8 @@ where
280286
}
281287
}
282288
}
289+
#[cfg(swc_ast_unknown)]
290+
_ => panic!("unable to access unknown nodes"),
283291
}
284292
}
285293

0 commit comments

Comments
 (0)