Skip to content

Commit

Permalink
refactor(visit): Reduce expanded LOCs (#7442)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 authored May 24, 2023
1 parent c1f2b4a commit e83368e
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 28 deletions.
6 changes: 3 additions & 3 deletions crates/swc_ecma_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ name = "swc_ecma_utils"
repository = "https://github.com/swc-project/swc.git"
version = "0.117.10"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[lib]
bench = false
Expand Down
191 changes: 191 additions & 0 deletions crates/swc_visit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
//! `VisitMutAstPath` and `FoldAstPath` can be used to transform AST nodes with
//! the path to the node.
use std::ops::{Deref, DerefMut};

pub use either::Either;
pub use swc_visit_macros::define;

Expand Down Expand Up @@ -251,13 +253,27 @@ where
Self { path }
}

pub fn with_guard(&mut self, kind: K) -> AstKindPathGuard<K> {
self.path.push(kind);

AstKindPathGuard { path: self }
}

pub fn with_index_guard(&mut self, index: usize) -> AstKindPathIndexGuard<K> {
self.path.last_mut().unwrap().set_index(index);

AstKindPathIndexGuard { path: self }
}

#[deprecated = "Use with_guard instead"]
pub fn with<Ret>(&mut self, path: K, op: impl FnOnce(&mut Self) -> Ret) -> Ret {
self.path.push(path);
let ret = op(self);
self.path.pop();
ret
}

#[deprecated = "Use with_index_guard instead"]
pub fn with_index<Ret>(&mut self, index: usize, op: impl FnOnce(&mut Self) -> Ret) -> Ret {
self.path.last_mut().unwrap().set_index(index);
let res = op(self);
Expand All @@ -266,6 +282,82 @@ where
}
}

pub struct AstKindPathGuard<'a, K>
where
K: ParentKind,
{
path: &'a mut AstKindPath<K>,
}

impl<K> Deref for AstKindPathGuard<'_, K>
where
K: ParentKind,
{
type Target = AstKindPath<K>;

#[inline]
fn deref(&self) -> &Self::Target {
self.path
}
}

impl<K> DerefMut for AstKindPathGuard<'_, K>
where
K: ParentKind,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.path
}
}

impl<K> Drop for AstKindPathGuard<'_, K>
where
K: ParentKind,
{
fn drop(&mut self) {
self.path.path.pop();
}
}

pub struct AstKindPathIndexGuard<'a, K>
where
K: ParentKind,
{
path: &'a mut AstKindPath<K>,
}

impl<K> Deref for AstKindPathIndexGuard<'_, K>
where
K: ParentKind,
{
type Target = AstKindPath<K>;

#[inline]
fn deref(&self) -> &Self::Target {
self.path
}
}

impl<K> DerefMut for AstKindPathIndexGuard<'_, K>
where
K: ParentKind,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.path
}
}

impl<K> Drop for AstKindPathIndexGuard<'_, K>
where
K: ParentKind,
{
fn drop(&mut self) {
self.path.path.last_mut().unwrap().set_index(usize::MAX);
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AstNodePath<N>
where
Expand Down Expand Up @@ -310,6 +402,21 @@ where
&self.kinds
}

pub fn with_guard(&mut self, node: N) -> AstNodePathGuard<N> {
self.kinds.path.push(node.kind());
self.path.push(node);

AstNodePathGuard { path: self }
}

pub fn with_index_guard(&mut self, index: usize) -> AstNodePathIndexGuard<N> {
self.kinds.path.last_mut().unwrap().set_index(index);
self.path.last_mut().unwrap().set_index(index);

AstNodePathIndexGuard { path: self }
}

#[deprecated = "Use with_guard instead"]
pub fn with<F, Ret>(&mut self, node: N, op: F) -> Ret
where
F: for<'aa> FnOnce(&'aa mut AstNodePath<N>) -> Ret,
Expand All @@ -325,6 +432,7 @@ where
ret
}

#[deprecated = "Use with_index_guard instead"]
pub fn with_index<F, Ret>(&mut self, index: usize, op: F) -> Ret
where
F: for<'aa> FnOnce(&'aa mut AstNodePath<N>) -> Ret,
Expand All @@ -351,3 +459,86 @@ pub trait NodeRef: Copy {
pub trait ParentKind: Copy {
fn set_index(&mut self, index: usize);
}

pub struct AstNodePathGuard<'a, N>
where
N: NodeRef,
{
path: &'a mut AstNodePath<N>,
}

impl<N> Deref for AstNodePathGuard<'_, N>
where
N: NodeRef,
{
type Target = AstNodePath<N>;

#[inline]
fn deref(&self) -> &Self::Target {
self.path
}
}

impl<N> DerefMut for AstNodePathGuard<'_, N>
where
N: NodeRef,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.path
}
}

impl<N> Drop for AstNodePathGuard<'_, N>
where
N: NodeRef,
{
fn drop(&mut self) {
self.path.path.pop();
self.path.kinds.path.pop();
}
}

pub struct AstNodePathIndexGuard<'a, N>
where
N: NodeRef,
{
path: &'a mut AstNodePath<N>,
}

impl<N> Deref for AstNodePathIndexGuard<'_, N>
where
N: NodeRef,
{
type Target = AstNodePath<N>;

#[inline]
fn deref(&self) -> &Self::Target {
self.path
}
}

impl<N> DerefMut for AstNodePathIndexGuard<'_, N>
where
N: NodeRef,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.path
}
}

impl<N> Drop for AstNodePathIndexGuard<'_, N>
where
N: NodeRef,
{
fn drop(&mut self) {
self.path.path.last_mut().unwrap().set_index(usize::MAX);
self.path
.kinds
.path
.last_mut()
.unwrap()
.set_index(usize::MAX);
}
}
51 changes: 26 additions & 25 deletions crates/swc_visit_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2249,9 +2249,10 @@ fn visit_expr(
ast_path_expr,
},
{
__ast_path.with(ast_path_expr, |__ast_path| {
visitor.visit_name(expr, __ast_path)
})
{
let mut __ast_path = __ast_path.with_guard(ast_path_expr);
visitor.visit_name(expr, &mut *__ast_path)
}
}
)
.parse()
Expand Down Expand Up @@ -2983,10 +2984,11 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
n.into_iter()
.enumerate()
.map(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
swc_visit::util::map::Map::map(v, |v| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path =
__ast_path.with_index_guard(idx);

swc_visit::util::map::Map::map(v, |v| {
_visitor.ident(v, &mut *__ast_path)
})
})
.collect()
Expand Down Expand Up @@ -3017,9 +3019,9 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
n.into_iter()
.enumerate()
.map(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);

_visitor.ident(v, &mut *__ast_path)
})
.collect()
})
Expand All @@ -3036,9 +3038,9 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
Vars { ident },
({
n.iter_mut().enumerate().for_each(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);

_visitor.ident(v, &mut *__ast_path)
})
})
)
Expand All @@ -3054,9 +3056,9 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
Vars { ident },
({
n.iter().enumerate().for_each(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v.as_ref(), __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);

_visitor.ident(v.as_ref(), &mut *__ast_path)
})
})
)
Expand All @@ -3080,9 +3082,8 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
n.into_iter()
.enumerate()
.map(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);
_visitor.ident(v, &mut *__ast_path)
})
.collect()
})
Expand All @@ -3099,9 +3100,9 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
Vars { ident },
({
n.iter_mut().enumerate().for_each(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);

_visitor.ident(v, &mut *__ast_path)
})
})
)
Expand All @@ -3117,9 +3118,9 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
Vars { ident },
({
n.iter().enumerate().for_each(|(idx, v)| {
__ast_path.with_index(idx, |__ast_path| {
_visitor.ident(v, __ast_path)
})
let mut __ast_path = __ast_path.with_index_guard(idx);

_visitor.ident(v, &mut *__ast_path)
})
})
)
Expand Down

1 comment on commit e83368e

@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: e83368e Previous: a37d59a Ratio
es/full/bugs-1 247068 ns/iter (± 6792) 304142 ns/iter (± 8032) 0.81
es/full/minify/libraries/antd 1193603110 ns/iter (± 12343520) 1471849195 ns/iter (± 16320727) 0.81
es/full/minify/libraries/d3 238862495 ns/iter (± 3042735) 294844717 ns/iter (± 6422087) 0.81
es/full/minify/libraries/echarts 958587281 ns/iter (± 5002279) 1162817838 ns/iter (± 8279494) 0.82
es/full/minify/libraries/jquery 76929390 ns/iter (± 68122) 90455361 ns/iter (± 663060) 0.85
es/full/minify/libraries/lodash 86898650 ns/iter (± 265016) 104655280 ns/iter (± 1008250) 0.83
es/full/minify/libraries/moment 45021412 ns/iter (± 81067) 52032176 ns/iter (± 566305) 0.87
es/full/minify/libraries/react 16345991 ns/iter (± 13957) 19095268 ns/iter (± 86754) 0.86
es/full/minify/libraries/terser 198489457 ns/iter (± 380089) 238391318 ns/iter (± 1517848) 0.83
es/full/minify/libraries/three 341150683 ns/iter (± 906681) 415285555 ns/iter (± 4639614) 0.82
es/full/minify/libraries/typescript 2414893646 ns/iter (± 9167976) 2906442836 ns/iter (± 26697329) 0.83
es/full/minify/libraries/victory 507159653 ns/iter (± 3130605) 630606369 ns/iter (± 6281960) 0.80
es/full/minify/libraries/vue 109430986 ns/iter (± 377134) 128711881 ns/iter (± 801346) 0.85
es/full/codegen/es3 29849 ns/iter (± 92) 33551 ns/iter (± 140) 0.89
es/full/codegen/es5 29816 ns/iter (± 29) 33687 ns/iter (± 130) 0.89
es/full/codegen/es2015 29808 ns/iter (± 44) 33381 ns/iter (± 246) 0.89
es/full/codegen/es2016 29798 ns/iter (± 40) 33202 ns/iter (± 172) 0.90
es/full/codegen/es2017 29731 ns/iter (± 67) 33328 ns/iter (± 283) 0.89
es/full/codegen/es2018 29793 ns/iter (± 62) 33578 ns/iter (± 261) 0.89
es/full/codegen/es2019 29731 ns/iter (± 43) 33452 ns/iter (± 204) 0.89
es/full/codegen/es2020 29808 ns/iter (± 45) 33327 ns/iter (± 461) 0.89
es/full/all/es3 158088554 ns/iter (± 1300986) 181784204 ns/iter (± 2519841) 0.87
es/full/all/es5 150974692 ns/iter (± 936058) 174028559 ns/iter (± 1349305) 0.87
es/full/all/es2015 112304074 ns/iter (± 895849) 135326845 ns/iter (± 3030267) 0.83
es/full/all/es2016 110841008 ns/iter (± 570037) 134103164 ns/iter (± 1752021) 0.83
es/full/all/es2017 110147722 ns/iter (± 653328) 132195011 ns/iter (± 1975697) 0.83
es/full/all/es2018 108709006 ns/iter (± 705359) 128319007 ns/iter (± 1971524) 0.85
es/full/all/es2019 108649492 ns/iter (± 622845) 125794460 ns/iter (± 1457570) 0.86
es/full/all/es2020 102619602 ns/iter (± 765065) 118310713 ns/iter (± 1014945) 0.87
es/full/parser 465276 ns/iter (± 5095) 510343 ns/iter (± 8698) 0.91
es/full/base/fixer 18167 ns/iter (± 33) 23729 ns/iter (± 165) 0.77
es/full/base/resolver_and_hygiene 74412 ns/iter (± 172) 83340 ns/iter (± 672) 0.89
serialization of serde 113 ns/iter (± 1) 123 ns/iter (± 0) 0.92
css/minify/libraries/bootstrap 23311094 ns/iter (± 18633) 27108215 ns/iter (± 380675) 0.86
css/visitor/compare/clone 1649511 ns/iter (± 5023) 2127916 ns/iter (± 18177) 0.78
css/visitor/compare/visit_mut_span 1775666 ns/iter (± 3483) 2285285 ns/iter (± 12605) 0.78
css/visitor/compare/visit_mut_span_panic 1852991 ns/iter (± 2167) 2324034 ns/iter (± 13857) 0.80
css/visitor/compare/fold_span 2546265 ns/iter (± 14193) 3006473 ns/iter (± 17048) 0.85
css/visitor/compare/fold_span_panic 2737156 ns/iter (± 9198) 3168434 ns/iter (± 24608) 0.86
css/lexer/bootstrap_5_1_3 4595520 ns/iter (± 5365) 5136114 ns/iter (± 36441) 0.89
css/lexer/foundation_6_7_4 3877914 ns/iter (± 3003) 4320827 ns/iter (± 36217) 0.90
css/lexer/tailwind_3_1_1 734733 ns/iter (± 926) 813126 ns/iter (± 6599) 0.90
css/parser/bootstrap_5_1_3 18164266 ns/iter (± 37614) 20681296 ns/iter (± 209400) 0.88
css/parser/foundation_6_7_4 14533728 ns/iter (± 14431) 16366075 ns/iter (± 138599) 0.89
css/parser/tailwind_3_1_1 2810510 ns/iter (± 3206) 3163007 ns/iter (± 10702) 0.89
es/codegen/colors 734312 ns/iter (± 400746) 735083 ns/iter (± 394687) 1.00
es/codegen/large 3002699 ns/iter (± 1592293) 3189093 ns/iter (± 1625321) 0.94
es/codegen/with-parser/colors 42875 ns/iter (± 495) 47025 ns/iter (± 641) 0.91
es/codegen/with-parser/large 462780 ns/iter (± 519) 506354 ns/iter (± 1987) 0.91
es/minify/libraries/antd 1046555640 ns/iter (± 8958842) 1316075109 ns/iter (± 17031435) 0.80
es/minify/libraries/d3 212522116 ns/iter (± 332971) 249742099 ns/iter (± 2965323) 0.85
es/minify/libraries/echarts 828832121 ns/iter (± 4700361) 1006960539 ns/iter (± 12743856) 0.82
es/minify/libraries/jquery 68877831 ns/iter (± 84095) 79993526 ns/iter (± 986966) 0.86
es/minify/libraries/lodash 79479258 ns/iter (± 223510) 95836981 ns/iter (± 657318) 0.83
es/minify/libraries/moment 40306118 ns/iter (± 42513) 46452098 ns/iter (± 390379) 0.87
es/minify/libraries/react 14829011 ns/iter (± 30605) 17222723 ns/iter (± 129492) 0.86
es/minify/libraries/terser 174388026 ns/iter (± 473272) 206944091 ns/iter (± 2691213) 0.84
es/minify/libraries/three 291111091 ns/iter (± 950757) 349793239 ns/iter (± 4731022) 0.83
es/minify/libraries/typescript 2087400327 ns/iter (± 4677181) 2523936217 ns/iter (± 20246302) 0.83
es/minify/libraries/victory 431102588 ns/iter (± 1317611) 537740582 ns/iter (± 8652308) 0.80
es/minify/libraries/vue 99786638 ns/iter (± 72562) 117614715 ns/iter (± 634126) 0.85
es/visitor/compare/clone 1998846 ns/iter (± 6409) 2288678 ns/iter (± 16986) 0.87
es/visitor/compare/visit_mut_span 2338271 ns/iter (± 6228) 2656915 ns/iter (± 9334) 0.88
es/visitor/compare/visit_mut_span_panic 2352091 ns/iter (± 3750) 2695242 ns/iter (± 17104) 0.87
es/visitor/compare/fold_span 3426282 ns/iter (± 6576) 3733344 ns/iter (± 18144) 0.92
es/visitor/compare/fold_span_panic 3561576 ns/iter (± 6170) 3894170 ns/iter (± 20268) 0.91
es/lexer/colors 11491 ns/iter (± 23) 13076 ns/iter (± 152) 0.88
es/lexer/angular 5664463 ns/iter (± 5863) 6395196 ns/iter (± 16592) 0.89
es/lexer/backbone 736992 ns/iter (± 1502) 779038 ns/iter (± 4307) 0.95
es/lexer/jquery 4156946 ns/iter (± 15341) 4378653 ns/iter (± 18820) 0.95
es/lexer/jquery mobile 6376301 ns/iter (± 7403) 6865930 ns/iter (± 53683) 0.93
es/lexer/mootools 3259789 ns/iter (± 8215) 3452281 ns/iter (± 33399) 0.94
es/lexer/underscore 601752 ns/iter (± 1148) 641452 ns/iter (± 4132) 0.94
es/lexer/three 19425821 ns/iter (± 33789) 20690391 ns/iter (± 86461) 0.94
es/lexer/yui 3545801 ns/iter (± 4734) 3860632 ns/iter (± 32143) 0.92
es/parser/colors 26215 ns/iter (± 49) 28100 ns/iter (± 177) 0.93
es/parser/angular 13262418 ns/iter (± 62704) 14864669 ns/iter (± 154750) 0.89
es/parser/backbone 1974638 ns/iter (± 8696) 2141299 ns/iter (± 25011) 0.92
es/parser/jquery 10706961 ns/iter (± 54957) 11631538 ns/iter (± 153731) 0.92
es/parser/jquery mobile 16567236 ns/iter (± 76164) 17887789 ns/iter (± 135588) 0.93
es/parser/mootools 8256003 ns/iter (± 17967) 8771152 ns/iter (± 46660) 0.94
es/parser/underscore 1698398 ns/iter (± 9470) 1805298 ns/iter (± 16408) 0.94
es/parser/three 46526482 ns/iter (± 266636) 50680148 ns/iter (± 925860) 0.92
es/parser/yui 8169172 ns/iter (± 29123) 8961542 ns/iter (± 56034) 0.91
es/preset-env/usage/builtin_type 130723 ns/iter (± 34145) 136616 ns/iter (± 34686) 0.96
es/preset-env/usage/property 15326 ns/iter (± 70) 19671 ns/iter (± 143) 0.78
es/resolver/typescript 90545576 ns/iter (± 665378) 113028450 ns/iter (± 4005690) 0.80
es/fixer/typescript 63395301 ns/iter (± 287447) 80580220 ns/iter (± 1265859) 0.79
es/hygiene/typescript 129712075 ns/iter (± 824717) 167909030 ns/iter (± 1569444) 0.77
es/resolver_with_hygiene/typescript 234078526 ns/iter (± 10381613) 304759892 ns/iter (± 7844664) 0.77
es/visitor/base-perf/module_clone 58994 ns/iter (± 220) 79643 ns/iter (± 710) 0.74
es/visitor/base-perf/fold_empty 62881 ns/iter (± 200) 88592 ns/iter (± 576) 0.71
es/visitor/base-perf/fold_noop_impl_all 63698 ns/iter (± 358) 89535 ns/iter (± 380) 0.71
es/visitor/base-perf/fold_noop_impl_vec 63562 ns/iter (± 235) 90590 ns/iter (± 553) 0.70
es/visitor/base-perf/boxing_boxed_clone 52 ns/iter (± 0) 55 ns/iter (± 0) 0.95
es/visitor/base-perf/boxing_unboxed_clone 36 ns/iter (± 0) 40 ns/iter (± 0) 0.90
es/visitor/base-perf/boxing_boxed 111 ns/iter (± 0) 102 ns/iter (± 0) 1.09
es/visitor/base-perf/boxing_unboxed 76 ns/iter (± 0) 79 ns/iter (± 0) 0.96
es/visitor/base-perf/visit_empty 0 ns/iter (± 0)
es/visitor/base-perf/visit_contains_this 2690 ns/iter (± 29) 3538 ns/iter (± 103) 0.76
es/base/parallel/resolver/typescript 4283932699 ns/iter (± 296052827) 6300636997 ns/iter (± 356319528) 0.68
es/base/parallel/hygiene/typescript 1563778041 ns/iter (± 51572237) 1982428692 ns/iter (± 19695521) 0.79
misc/visitors/time-complexity/time 5 104 ns/iter (± 0) 102 ns/iter (± 0) 1.02
misc/visitors/time-complexity/time 10 300 ns/iter (± 0) 314 ns/iter (± 2) 0.96
misc/visitors/time-complexity/time 15 726 ns/iter (± 8) 630 ns/iter (± 19) 1.15
misc/visitors/time-complexity/time 20 1175 ns/iter (± 1) 1143 ns/iter (± 7) 1.03
misc/visitors/time-complexity/time 40 3804 ns/iter (± 18) 5923 ns/iter (± 49) 0.64
misc/visitors/time-complexity/time 60 7843 ns/iter (± 19) 15174 ns/iter (± 131) 0.52
es/full-target/es2016 227621 ns/iter (± 5897) 250154 ns/iter (± 2142) 0.91
es/full-target/es2017 215727 ns/iter (± 439) 243273 ns/iter (± 2302) 0.89
es/full-target/es2018 203190 ns/iter (± 355) 230100 ns/iter (± 1695) 0.88
es2020_nullish_coalescing 68590 ns/iter (± 398) 90140 ns/iter (± 457) 0.76
es2020_optional_chaining 97846 ns/iter (± 409) 121003 ns/iter (± 980) 0.81
es2022_class_properties 114348 ns/iter (± 403) 146338 ns/iter (± 1363) 0.78
es2018_object_rest_spread 72981 ns/iter (± 472) 94348 ns/iter (± 737) 0.77
es2019_optional_catch_binding 62613 ns/iter (± 169) 83334 ns/iter (± 721) 0.75
es2017_async_to_generator 62903 ns/iter (± 207) 84110 ns/iter (± 411) 0.75
es2016_exponentiation 67328 ns/iter (± 341) 88628 ns/iter (± 614) 0.76
es2015_arrow 70832 ns/iter (± 280) 91820 ns/iter (± 977) 0.77
es2015_block_scoped_fn 68045 ns/iter (± 135) 90472 ns/iter (± 511) 0.75
es2015_block_scoping 118262 ns/iter (± 1186) 167604 ns/iter (± 1353) 0.71

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

Please # to comment.