Skip to content

Commit bc666be

Browse files
authoredFeb 19, 2025··
feat(es/visit): Introduce core-only visitors (#10049)
**Description:** These types will be used by core transforms.
1 parent c739748 commit bc666be

File tree

7 files changed

+98488
-8
lines changed

7 files changed

+98488
-8
lines changed
 

‎Cargo.lock

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/swc_ecma_visit_std/Cargo.toml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[package]
2+
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
3+
description = "Visitors for swc ecmascript nodes which works on stable rustc"
4+
documentation = "https://rustdoc.swc.rs/swc_ecma_visit_std/"
5+
edition = { workspace = true }
6+
license = { workspace = true }
7+
name = "swc_ecma_visit_std"
8+
repository = { workspace = true }
9+
version = "1.0.0"
10+
11+
[package.metadata.docs.rs]
12+
all-features = true
13+
rustdoc-args = ["--cfg", "docsrs"]
14+
15+
[lib]
16+
bench = false
17+
18+
[features]
19+
debug = []
20+
default = []
21+
path = []
22+
serde-impl = ["serde"]
23+
24+
[dependencies]
25+
new_debug_unreachable = { workspace = true }
26+
num-bigint = { workspace = true, features = ["serde"] }
27+
serde = { workspace = true, optional = true, features = ["derive"] }
28+
tracing = { workspace = true }
29+
30+
swc_atoms = { version = "4.0.0", path = "../swc_atoms" }
31+
swc_common = { version = "7.0.0", path = "../swc_common" }
32+
swc_ecma_ast = { version = "7.0.0", path = "../swc_ecma_ast" }
33+
swc_visit = { version = "2.0.0", path = "../swc_visit" }

‎crates/swc_ecma_visit_std/src/generated.rs

+98,366
Large diffs are not rendered by default.

‎crates/swc_ecma_visit_std/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![cfg_attr(docsrs, feature(doc_cfg))]
2+
3+
#[doc(hidden)]
4+
pub extern crate swc_ecma_ast;
5+
6+
pub use self::generated::*;
7+
8+
mod generated;

‎tools/generate-code/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ anyhow = { workspace = true }
1212
clap = { version = "4.5.9", features = ["derive"] }
1313
proc-macro2 = { workspace = true }
1414
quote = { workspace = true }
15+
swc_cached = { version = "2.0.0", path = "../../crates/swc_cached" }
1516
syn = { workspace = true, features = ["full", "visit-mut", "extra-traits"] }
1617
walkdir = { workspace = true }

‎tools/generate-code/src/generators/visitor.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,28 @@ use std::collections::HashSet;
33
use inflector::Inflector;
44
use proc_macro2::{Span, TokenStream};
55
use quote::{quote, ToTokens};
6+
use swc_cached::regex::CachedRegex;
67
use syn::{
78
parse_quote, Arm, Attribute, Expr, Field, Fields, File, GenericArgument, Ident, Item, Lit,
89
LitInt, Path, PathArguments, Stmt, TraitItem, Type,
910
};
1011

11-
pub fn generate(crate_name: &Ident, node_types: &[&Item]) -> File {
12+
pub fn generate(crate_name: &Ident, node_types: &[&Item], excluded_types: &[String]) -> File {
1213
let mut output = File {
1314
shebang: None,
1415
attrs: Vec::new(),
1516
items: Vec::new(),
1617
};
1718
let mut all_types = all_field_types(node_types).into_iter().collect::<Vec<_>>();
19+
20+
if !excluded_types.is_empty() {
21+
all_types.retain(|ty| {
22+
!excluded_types
23+
.iter()
24+
.any(|type_name| ty.contains_type(type_name))
25+
});
26+
}
27+
1828
all_types.sort_by_cached_key(|v| v.method_name());
1929

2030
let mut typedefs = HashSet::new();
@@ -59,7 +69,11 @@ pub fn generate(crate_name: &Ident, node_types: &[&Item]) -> File {
5969

6070
for &kind in [TraitKind::Visit, TraitKind::VisitMut, TraitKind::Fold].iter() {
6171
for &variant in [Variant::Normal, Variant::AstPath].iter() {
62-
let g = Generator { kind, variant };
72+
let g = Generator {
73+
kind,
74+
variant,
75+
excluded_types,
76+
};
6377

6478
output.items.extend(g.declare_visit_trait(&all_types));
6579

@@ -135,6 +149,15 @@ impl FieldType {
135149
},
136150
}
137151
}
152+
153+
fn contains_type(&self, type_name: &str) -> bool {
154+
let regex = CachedRegex::new(type_name).expect("failed to create regex");
155+
156+
match self {
157+
FieldType::Normal(name) => regex.is_match(name),
158+
FieldType::Generic(name, ty) => regex.is_match(name) || ty.contains_type(type_name),
159+
}
160+
}
138161
}
139162

140163
fn all_field_types(node_types: &[&Item]) -> HashSet<FieldType> {
@@ -283,12 +306,14 @@ impl Variant {
283306
}
284307
}
285308

286-
struct Generator {
309+
struct Generator<'a> {
287310
kind: TraitKind,
288311
variant: Variant,
312+
313+
excluded_types: &'a [String],
289314
}
290315

291-
impl Generator {
316+
impl Generator<'_> {
292317
fn should_skip(&self, ty: &Type) -> bool {
293318
if let Some(ty) = extract_generic("Box", ty) {
294319
return self.should_skip(ty);
@@ -304,9 +329,16 @@ impl Generator {
304329

305330
let ty = to_field_ty(ty);
306331
match ty {
307-
Some(..) => {}
332+
Some(ty) => {
333+
for excluded_type in self.excluded_types {
334+
if ty.contains_type(excluded_type) {
335+
return true;
336+
}
337+
}
338+
}
308339
None => return true,
309340
}
341+
310342
false
311343
}
312344

‎tools/generate-code/src/main.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
55
use anyhow::{bail, Context, Result};
66
use clap::Parser;
77
use proc_macro2::Span;
8+
use swc_cached::regex::CachedRegex;
89
use syn::{Ident, Item};
910

1011
use crate::types::qualify_types;
@@ -39,7 +40,7 @@ fn main() -> Result<()> {
3940
Ok(())
4041
}
4142

42-
fn run_visitor_codegen(input_dir: &Path, output: &Path, excludes: &[String]) -> Result<()> {
43+
fn run_visitor_codegen(input_dir: &Path, output: &Path, excluded_types: &[String]) -> Result<()> {
4344
let crate_name = Ident::new(
4445
input_dir.file_name().unwrap().to_str().unwrap(),
4546
Span::call_site(),
@@ -72,7 +73,14 @@ fn run_visitor_codegen(input_dir: &Path, output: &Path, excludes: &[String]) ->
7273
_ => return false,
7374
};
7475

75-
!excludes.contains(&ident.to_string())
76+
for type_name in excluded_types {
77+
let regex = CachedRegex::new(type_name).expect("failed to create regex");
78+
if regex.is_match(&ident.to_string()) {
79+
return false;
80+
}
81+
}
82+
83+
true
7684
});
7785

7886
all_type_defs.sort_by_key(|item| match item {
@@ -81,7 +89,7 @@ fn run_visitor_codegen(input_dir: &Path, output: &Path, excludes: &[String]) ->
8189
_ => None,
8290
});
8391

84-
let file = generators::visitor::generate(&crate_name, &all_type_defs);
92+
let file = generators::visitor::generate(&crate_name, &all_type_defs, excluded_types);
8593

8694
let output_content = quote::quote!(#file).to_string();
8795

@@ -125,6 +133,23 @@ fn test_ecmascript() {
125133
.unwrap();
126134
}
127135

136+
#[test]
137+
fn test_ecmascript_std() {
138+
run_visitor_codegen(
139+
Path::new("../../crates/swc_ecma_ast"),
140+
Path::new("../../crates/swc_ecma_visit_std/src/generated.rs"),
141+
&[
142+
"Align64".into(),
143+
"EncodeBigInt".into(),
144+
"EsVersion".into(),
145+
"FnPass".into(),
146+
"Accessibility".into(),
147+
"^Ts.*".into(),
148+
],
149+
)
150+
.unwrap();
151+
}
152+
128153
#[test]
129154
fn test_css() {
130155
run_visitor_codegen(

0 commit comments

Comments
 (0)
Please sign in to comment.