Skip to content

Commit

Permalink
doc(visit): Add docs for visitors (#5137)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Jul 7, 2022
1 parent 297228a commit 76de911
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 4 deletions.
9 changes: 9 additions & 0 deletions crates/swc_visit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@
//! ```
//!
//! If you want to allow using path-aware visitor.
//!
//!
//! # Path-aware visitor
//!
//! Path-aware visitor is a visitor that can be used to visit AST nodes with
//! current path from the entrypoint.
//!
//! `VisitMutAstPath` and `FoldAstPath` can be used to transform AST nodes with
//! the path to the node.

pub use either::Either;
pub use swc_visit_macros::define;
Expand Down
123 changes: 119 additions & 4 deletions crates/swc_visit_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,32 @@ impl Mode {
Mode::VisitAll => None,
}
}

fn name_of_trait_for_ast(self) -> Option<&'static str> {
Some(match self {
Mode::VisitAll => return None,
Mode::Fold(VisitorVariant::Normal) => "FoldWith",
Mode::Visit(VisitorVariant::Normal) => "VisitWiht",
Mode::VisitMut(VisitorVariant::Normal) => "VisitMutWith",
Mode::Visit(VisitorVariant::WithPath) => "VisitWithPath",
Mode::VisitMut(VisitorVariant::WithPath) => "VisitMutWithPath",
Mode::Fold(VisitorVariant::WithPath) => "FoldWithPath",
})
}

fn name_of_trait_children_method_for_ast(self) -> Option<&'static str> {
Some(match self {
Mode::VisitAll => return None,
Mode::Fold(VisitorVariant::Normal) => "fold_children_with",
Mode::Fold(VisitorVariant::WithPath) => "fold_children_with_path",

Mode::Visit(VisitorVariant::Normal) => "visit_children_with",
Mode::Visit(VisitorVariant::WithPath) => "visit_children_with_path",

Mode::VisitMut(VisitorVariant::Normal) => "visit_mut_children_with",
Mode::VisitMut(VisitorVariant::WithPath) => "visit_mut_children_with_path",
})
}
}

/// This creates `Visit`. This is extensible visitor generator, and it
Expand Down Expand Up @@ -620,6 +646,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
Trait: Ident::new(mode.trait_name(), call_site()),
},
{
/// Visits children of the nodes with the given visitor.
///
/// This is the default implementation of a method of
/// [Fold].
#[allow(unused_variables)]
pub fn fn_name<V: ?Sized + Trait>(_visitor: &mut V, n: Type) -> Type {
default_body
Expand All @@ -635,6 +665,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
Trait: Ident::new(mode.trait_name(), call_site()),
},
{
/// Visits children of the nodes with the given visitor.
///
/// This is the default implementation of a method of
/// [VisitMut].
#[allow(unused_variables)]
pub fn fn_name<V: ?Sized + Trait>(_visitor: &mut V, n: Type) {
default_body
Expand All @@ -650,6 +684,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
Trait: Ident::new(mode.trait_name(), call_site()),
},
{
/// Visits children of the nodes with the given visitor.
///
/// This is the default implementation of a method of
/// [Visit].
#[allow(unused_variables)]
pub fn fn_name<V: ?Sized + Trait>(_visitor: &mut V, n: Type) {
default_body
Expand Down Expand Up @@ -956,7 +994,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {

let trait_decl = match mode {
Mode::Visit(VisitorVariant::Normal) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
pub trait VisitWith<V: ?Sized + Visit> {
/// Calls a visitor method (v.visit_xxx) with self.
fn visit_with(&self, v: &mut V);

/// Visit children nodes of self with `v`
Expand All @@ -980,17 +1021,26 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}),

Mode::Visit(VisitorVariant::WithPath) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
#[cfg(any(feature = "path", docsrs))]
#[cfg_attr(docsrs, doc(cfg(feature = "path")))]
pub trait VisitWithPath<V: ?Sized + VisitAstPath> {
/// Calls a visitor method (v.visit_xxx) with self and the
/// ast path.
fn visit_with_path<'ast, 'r>(
&'ast self,
v: &mut V,
ast_path: &mut AstNodePath<'r>,
) where
'ast: 'r;

/// Visit children nodes of self with `v`
/// Visit children nodes with v and ast path appended
/// [AstNodeRef] describing `self`. The ast path will
/// be resotred when this method returns.
///
/// This is the default implementaton of a handler method in
/// [VisitAstPath].
fn visit_children_with_path<'ast, 'r>(
&'ast self,
v: &mut V,
Expand Down Expand Up @@ -1030,7 +1080,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}),

Mode::VisitAll => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
pub trait VisitAllWith<V: ?Sized + VisitAll> {
/// Calls a visitor method (v.visit_xxx) with self.
fn visit_all_with(&self, v: &mut V);

/// Visit children nodes of self with `v`
Expand All @@ -1053,7 +1106,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}
}),
Mode::Fold(VisitorVariant::Normal) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
pub trait FoldWith<V: ?Sized + Fold> {
/// Calls a visitor method (v.fold_xxx) with self.
fn fold_with(self, v: &mut V) -> Self;

/// Visit children nodes of self with `v`
Expand All @@ -1076,12 +1132,21 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}
}),
Mode::Fold(VisitorVariant::WithPath) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
#[cfg(any(feature = "path", docsrs))]
#[cfg_attr(docsrs, doc(cfg(feature = "path")))]
pub trait FoldWithPath<V: ?Sized + FoldAstPath> {
/// Calls a visitor method (v.fold_xxx) with self and the
/// ast path.
fn fold_with_path(self, v: &mut V, ast_path: &mut AstKindPath) -> Self;

/// Visit children nodes of self with `v`
/// Visit children nodes with v and ast path appended
/// [AstKind] of `self`. The ast path will
/// be resotred when this method returns.
///
/// This is the default implementaton of a handler method in
/// [FoldAstPath].
fn fold_children_with_path(self, v: &mut V, ast_path: &mut AstKindPath)
-> Self;
}
Expand Down Expand Up @@ -1112,7 +1177,10 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}
}),
Mode::VisitMut(VisitorVariant::Normal) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
pub trait VisitMutWith<V: ?Sized + VisitMut> {
/// Calls a visitor method (v.visit_mut_xxx) with self.
fn visit_mut_with(&mut self, v: &mut V);

fn visit_mut_children_with(&mut self, v: &mut V);
Expand All @@ -1133,11 +1201,21 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
}
}),
Mode::VisitMut(VisitorVariant::WithPath) => q!({
/// A utility trait implemented for ast nodes, and allow to
/// visit them with a visitor.
#[cfg(any(feature = "path", docsrs))]
#[cfg_attr(docsrs, doc(cfg(feature = "path")))]
pub trait VisitMutWithPath<V: ?Sized + VisitMutAstPath> {
/// Calls a visitor method (v.visit_mut_xxx) with self and
/// the ast path.
fn visit_mut_with_path(&mut self, v: &mut V, ast_path: &mut AstKindPath);

/// Visit children nodes with v and ast path appended
/// [AstKind] of `self`. The ast path will be resotred when
/// this method returns.
///
/// This is the default implementaton of a handler method in
/// [VisitMutAstPath].
fn visit_mut_children_with_path(
&mut self,
v: &mut V,
Expand All @@ -1147,6 +1225,7 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {

#[cfg(any(feature = "path", docsrs))]
#[cfg_attr(docsrs, doc(cfg(feature = "path")))]
#[doc = "Delegating implementation"]
impl<V, T> VisitMutWithPath<V> for Box<T>
where
V: ?Sized + VisitMutAstPath,
Expand Down Expand Up @@ -1802,6 +1881,42 @@ fn method_sig_from_ident(mode: Mode, v: &Ident) -> Signature {

/// Returns None if it's skipped.
fn make_method(mode: Mode, e: &Item, types: &mut Vec<Type>) -> Option<TraitItemMethod> {
let mut attrs = vec![];

{
let doc_str = "This method can be overriden to customize the visitor behavior.";
attrs.push(Attribute {
pound_token: def_site(),
style: AttrStyle::Outer,
bracket_token: def_site(),
path: q!({ doc }).parse(),
tokens: q!(Vars { doc_str },{ = doc_str }).into(),
});
attrs.push(Attribute {
pound_token: def_site(),
style: AttrStyle::Outer,
bracket_token: def_site(),
path: q!({ doc }).parse(),
tokens: q!(Vars { doc_str },{ = "" }).into(),
});
}

if let Some(trait_name) = mode.name_of_trait_for_ast() {
let doc_str = format!(
"This calls [`{}::{}`] on `n` by default. The default method visit children nodes \
with `self`.",
trait_name,
mode.name_of_trait_children_method_for_ast().unwrap()
);
attrs.push(Attribute {
pound_token: def_site(),
style: AttrStyle::Outer,
bracket_token: def_site(),
path: q!({ doc }).parse(),
tokens: q!(Vars { doc_str },{ = doc_str }).into(),
});
}

Some(match e {
Item::Struct(s) => {
let type_name = &s.ident;
Expand Down Expand Up @@ -1832,7 +1947,7 @@ fn make_method(mode: Mode, e: &Item, types: &mut Vec<Type>) -> Option<TraitItemM
let sig = method_sig_from_ident(mode, type_name);

TraitItemMethod {
attrs: vec![],
attrs,
sig,
default: Some(block),
semi_token: None,
Expand Down Expand Up @@ -1891,7 +2006,7 @@ fn make_method(mode: Mode, e: &Item, types: &mut Vec<Type>) -> Option<TraitItemM
};

TraitItemMethod {
attrs: vec![],
attrs,
sig: method_sig_from_ident(mode, type_name),
default: Some(block),
semi_token: None,
Expand Down

1 comment on commit 76de911

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 76de911 Previous: 82fbe15 Ratio
es/full/minify/libraries/antd 1932032371 ns/iter (± 27192327) 1737159978 ns/iter (± 69327068) 1.11
es/full/minify/libraries/d3 447705610 ns/iter (± 10775886) 419834462 ns/iter (± 8273207) 1.07
es/full/minify/libraries/echarts 1972100392 ns/iter (± 25516323) 1696483437 ns/iter (± 174884323) 1.16
es/full/minify/libraries/jquery 103848392 ns/iter (± 1391029) 92602832 ns/iter (± 2958594) 1.12
es/full/minify/libraries/lodash 138684407 ns/iter (± 1729480) 122684567 ns/iter (± 9149360) 1.13
es/full/minify/libraries/moment 61331634 ns/iter (± 192921) 54183640 ns/iter (± 8538205) 1.13
es/full/minify/libraries/react 21054237 ns/iter (± 13633336) 17984425 ns/iter (± 2213013) 1.17
es/full/minify/libraries/terser 721144174 ns/iter (± 16149487) 605034387 ns/iter (± 27987400) 1.19
es/full/minify/libraries/three 604773354 ns/iter (± 12285036) 557528510 ns/iter (± 74777222) 1.08
es/full/minify/libraries/typescript 4072868709 ns/iter (± 44530182) 3602783791 ns/iter (± 174014157) 1.13
es/full/minify/libraries/victory 838225191 ns/iter (± 13568734) 793929168 ns/iter (± 121445451) 1.06
es/full/minify/libraries/vue 157963025 ns/iter (± 3826967) 153692490 ns/iter (± 19867177) 1.03
es/full/codegen/es3 38538 ns/iter (± 919) 32827 ns/iter (± 806) 1.17
es/full/codegen/es5 39238 ns/iter (± 851) 32624 ns/iter (± 1208) 1.20
es/full/codegen/es2015 38858 ns/iter (± 1249) 32661 ns/iter (± 1662) 1.19
es/full/codegen/es2016 38738 ns/iter (± 1404) 32521 ns/iter (± 527) 1.19
es/full/codegen/es2017 38630 ns/iter (± 332) 32515 ns/iter (± 358) 1.19
es/full/codegen/es2018 38599 ns/iter (± 574) 32420 ns/iter (± 955) 1.19
es/full/codegen/es2019 38801 ns/iter (± 978) 32417 ns/iter (± 567) 1.20
es/full/codegen/es2020 38504 ns/iter (± 2797) 32411 ns/iter (± 873) 1.19
es/full/all/es3 225461943 ns/iter (± 4838514) 188959507 ns/iter (± 10805735) 1.19
es/full/all/es5 210626771 ns/iter (± 3070735) 176082204 ns/iter (± 10193715) 1.20
es/full/all/es2015 172908102 ns/iter (± 3799454) 139433201 ns/iter (± 8035580) 1.24
es/full/all/es2016 170967796 ns/iter (± 3569695) 139174267 ns/iter (± 8712111) 1.23
es/full/all/es2017 170988796 ns/iter (± 3002209) 138140943 ns/iter (± 4167970) 1.24
es/full/all/es2018 169002354 ns/iter (± 3348946) 136891244 ns/iter (± 4855019) 1.23
es/full/all/es2019 167171714 ns/iter (± 4138836) 136313185 ns/iter (± 5791381) 1.23
es/full/all/es2020 161487168 ns/iter (± 4402476) 136054460 ns/iter (± 10280012) 1.19
es/full/parser 868360 ns/iter (± 39428) 730875 ns/iter (± 34231) 1.19
es/full/base/fixer 36594 ns/iter (± 1211) 30424 ns/iter (± 2825) 1.20
es/full/base/resolver_and_hygiene 110092 ns/iter (± 3991) 88909 ns/iter (± 3715) 1.24
serialization of ast node 262 ns/iter (± 7) 208 ns/iter (± 4) 1.26
serialization of serde 274 ns/iter (± 3) 215 ns/iter (± 8) 1.27

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.