From 3b8f5cafc3981169a01b754b21c1d40a1b4af001 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Fri, 20 Jan 2023 21:30:24 +0800 Subject: [PATCH 01/14] perf(es/minifier): check whether a function is pure with O(1) cost --- crates/swc_ecma_minifier/src/metadata/mod.rs | 31 ++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 1d4b5c623a5c..e80351e7797b 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -1,3 +1,4 @@ +use rustc_hash::FxHashSet; use swc_common::{ comments::{Comment, CommentKind, Comments}, EqIgnoreSpan, Span, SyntaxContext, @@ -11,6 +12,15 @@ use swc_ecma_visit::{ use crate::option::CompressOptions; +#[derive(Debug, Eq, Hash)] +struct EqIgnoreSpanExprRef<'a>(&'a Expr); + +impl<'a> PartialEq for EqIgnoreSpanExprRef<'a> { + fn eq(&self, other: &Self) -> bool { + Ident::within_ignored_ctxt(|| self.0.eq_ignore_span(&other.0)) + } +} + #[cfg(test)] mod tests; @@ -21,10 +31,18 @@ pub(crate) fn info_marker<'a>( marks: Marks, // unresolved_mark: Mark, ) -> impl 'a + VisitMut { + let pure_fns = options.map(|options| { + options + .pure_funcs + .iter() + .map(|f| EqIgnoreSpanExprRef(f)) + .collect() + }); InfoMarker { options, comments, marks, + pure_fns, // unresolved_mark, state: Default::default(), } @@ -38,7 +56,7 @@ struct State { struct InfoMarker<'a> { options: Option<&'a CompressOptions>, - + pure_fns: Option>>, comments: Option<&'a dyn Comments>, marks: Marks, // unresolved_mark: Mark, @@ -124,17 +142,12 @@ impl VisitMut for InfoMarker<'_> { if self.has_pure(n.span) { n.span = n.span.apply_mark(self.marks.pure); - } else if let Some(options) = self.options { + } else if let Some(pure_fns) = &self.pure_fns { if let Callee::Expr(e) = &n.callee { // Check for pure_funcs - - if options - .pure_funcs - .iter() - .any(|pure_func| Ident::within_ignored_ctxt(|| e.eq_ignore_span(pure_func))) - { + if pure_fns.contains(&EqIgnoreSpanExprRef(e)) { n.span = n.span.apply_mark(self.marks.pure); - } + }; } } } From 03a152110b42b9069498f26cf96a0be3692bcb5b Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Fri, 20 Jan 2023 21:50:23 +0800 Subject: [PATCH 02/14] Clippy --- crates/swc_ecma_minifier/src/metadata/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index e80351e7797b..01d3a2506fae 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -31,7 +31,7 @@ pub(crate) fn info_marker<'a>( marks: Marks, // unresolved_mark: Mark, ) -> impl 'a + VisitMut { - let pure_fns = options.map(|options| { + let pure_funcs = options.map(|options| { options .pure_funcs .iter() @@ -42,7 +42,7 @@ pub(crate) fn info_marker<'a>( options, comments, marks, - pure_fns, + pure_funcs, // unresolved_mark, state: Default::default(), } @@ -55,8 +55,9 @@ struct State { } struct InfoMarker<'a> { + #[allow(dead_code)] options: Option<&'a CompressOptions>, - pure_fns: Option>>, + pure_funcs: Option>>, comments: Option<&'a dyn Comments>, marks: Marks, // unresolved_mark: Mark, @@ -142,7 +143,7 @@ impl VisitMut for InfoMarker<'_> { if self.has_pure(n.span) { n.span = n.span.apply_mark(self.marks.pure); - } else if let Some(pure_fns) = &self.pure_fns { + } else if let Some(pure_fns) = &self.pure_funcs { if let Callee::Expr(e) = &n.callee { // Check for pure_funcs if pure_fns.contains(&EqIgnoreSpanExprRef(e)) { From 017a12b81e7ad8a2611ff263727fb045543348ea Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Fri, 20 Jan 2023 22:03:55 +0800 Subject: [PATCH 03/14] Clippy --- crates/swc_ecma_minifier/src/metadata/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 01d3a2506fae..3c21032069bd 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -17,7 +17,7 @@ struct EqIgnoreSpanExprRef<'a>(&'a Expr); impl<'a> PartialEq for EqIgnoreSpanExprRef<'a> { fn eq(&self, other: &Self) -> bool { - Ident::within_ignored_ctxt(|| self.0.eq_ignore_span(&other.0)) + Ident::within_ignored_ctxt(|| self.0.eq_ignore_span(other.0)) } } From be7beb7936701bf0dbfc1f6449dc50e0f67a2f17 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Fri, 20 Jan 2023 23:37:11 +0800 Subject: [PATCH 04/14] impl Hash --- crates/swc_ecma_minifier/src/metadata/mod.rs | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 3c21032069bd..db8420197fc3 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -1,3 +1,5 @@ +use std::hash::Hash; + use rustc_hash::FxHashSet; use swc_common::{ comments::{Comment, CommentKind, Comments}, @@ -12,7 +14,7 @@ use swc_ecma_visit::{ use crate::option::CompressOptions; -#[derive(Debug, Eq, Hash)] +#[derive(Debug, Eq)] struct EqIgnoreSpanExprRef<'a>(&'a Expr); impl<'a> PartialEq for EqIgnoreSpanExprRef<'a> { @@ -21,6 +23,26 @@ impl<'a> PartialEq for EqIgnoreSpanExprRef<'a> { } } +impl<'a> Hash for EqIgnoreSpanExprRef<'a> { + fn hash(&self, state: &mut H) { + // In pratice, most of cases/input we are dealing with are Expr::Member or + // Expr::Ident. + match self.0 { + Expr::Ident(i) => { + i.sym.hash(state); + } + Expr::Member(i) => { + Self(&*i.obj).hash(state); + match &i.prop { + MemberProp::Ident(prop) => prop.sym.hash(state), + _ => {} + } + } + _ => {} + } + } +} + #[cfg(test)] mod tests; @@ -145,6 +167,12 @@ impl VisitMut for InfoMarker<'_> { n.span = n.span.apply_mark(self.marks.pure); } else if let Some(pure_fns) = &self.pure_funcs { if let Callee::Expr(e) = &n.callee { + println!("--pure_fns: {pure_fns:#?}"); + println!("e: {e:#?}"); + println!( + "pure_fns.contains(&EqIgnoreSpanExprRef(e)): {:?}", + pure_fns.contains(&EqIgnoreSpanExprRef(e)) + ); // Check for pure_funcs if pure_fns.contains(&EqIgnoreSpanExprRef(e)) { n.span = n.span.apply_mark(self.marks.pure); From 5ef8415776999509500cc478ec302f87f3fd26c9 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Fri, 20 Jan 2023 23:50:18 +0800 Subject: [PATCH 05/14] Clippy --- crates/swc_ecma_minifier/src/metadata/mod.rs | 26 +++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index db8420197fc3..3989e9a3c06d 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -15,15 +15,15 @@ use swc_ecma_visit::{ use crate::option::CompressOptions; #[derive(Debug, Eq)] -struct EqIgnoreSpanExprRef<'a>(&'a Expr); +struct HashEqIgnoreSpanExprRef<'a>(&'a Expr); -impl<'a> PartialEq for EqIgnoreSpanExprRef<'a> { +impl<'a> PartialEq for HashEqIgnoreSpanExprRef<'a> { fn eq(&self, other: &Self) -> bool { Ident::within_ignored_ctxt(|| self.0.eq_ignore_span(other.0)) } } -impl<'a> Hash for EqIgnoreSpanExprRef<'a> { +impl<'a> Hash for HashEqIgnoreSpanExprRef<'a> { fn hash(&self, state: &mut H) { // In pratice, most of cases/input we are dealing with are Expr::Member or // Expr::Ident. @@ -32,13 +32,15 @@ impl<'a> Hash for EqIgnoreSpanExprRef<'a> { i.sym.hash(state); } Expr::Member(i) => { - Self(&*i.obj).hash(state); - match &i.prop { - MemberProp::Ident(prop) => prop.sym.hash(state), - _ => {} + Self(&i.obj).hash(state); + if let MemberProp::Ident(prop) = &i.prop { + prop.sym.hash(state); } } - _ => {} + _ => { + // Other expression kind would fallback to the same empty hash. + // So, their will spend linear time to do comparisons. + } } } } @@ -57,7 +59,7 @@ pub(crate) fn info_marker<'a>( options .pure_funcs .iter() - .map(|f| EqIgnoreSpanExprRef(f)) + .map(|f| HashEqIgnoreSpanExprRef(f)) .collect() }); InfoMarker { @@ -79,7 +81,7 @@ struct State { struct InfoMarker<'a> { #[allow(dead_code)] options: Option<&'a CompressOptions>, - pure_funcs: Option>>, + pure_funcs: Option>>, comments: Option<&'a dyn Comments>, marks: Marks, // unresolved_mark: Mark, @@ -171,10 +173,10 @@ impl VisitMut for InfoMarker<'_> { println!("e: {e:#?}"); println!( "pure_fns.contains(&EqIgnoreSpanExprRef(e)): {:?}", - pure_fns.contains(&EqIgnoreSpanExprRef(e)) + pure_fns.contains(&HashEqIgnoreSpanExprRef(e)) ); // Check for pure_funcs - if pure_fns.contains(&EqIgnoreSpanExprRef(e)) { + if pure_fns.contains(&HashEqIgnoreSpanExprRef(e)) { n.span = n.span.apply_mark(self.marks.pure); }; } From 62fe5c3a3d434879991502593f7c19f42aef1a54 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 18:58:15 +0800 Subject: [PATCH 06/14] Add test and remove println --- crates/swc_ecma_minifier/src/metadata/mod.rs | 6 --- .../swc_ecma_minifier/src/metadata/tests.rs | 54 +++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 3989e9a3c06d..78006273a292 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -169,12 +169,6 @@ impl VisitMut for InfoMarker<'_> { n.span = n.span.apply_mark(self.marks.pure); } else if let Some(pure_fns) = &self.pure_funcs { if let Callee::Expr(e) = &n.callee { - println!("--pure_fns: {pure_fns:#?}"); - println!("e: {e:#?}"); - println!( - "pure_fns.contains(&EqIgnoreSpanExprRef(e)): {:?}", - pure_fns.contains(&HashEqIgnoreSpanExprRef(e)) - ); // Check for pure_funcs if pure_fns.contains(&HashEqIgnoreSpanExprRef(e)) { n.span = n.span.apply_mark(self.marks.pure); diff --git a/crates/swc_ecma_minifier/src/metadata/tests.rs b/crates/swc_ecma_minifier/src/metadata/tests.rs index 18bf8bc1c648..7e56a7849e23 100644 --- a/crates/swc_ecma_minifier/src/metadata/tests.rs +++ b/crates/swc_ecma_minifier/src/metadata/tests.rs @@ -158,3 +158,57 @@ // fn export_default_fn_1() { // assert_standalone("export default function f(module, exports) {}", 0); // } + +use std::hash::Hash; + +use rustc_hash::FxHashSet; +use swc_common::{Mark, DUMMY_SP}; +use swc_ecma_utils::{member_expr, quote_expr}; + +use super::HashEqIgnoreSpanExprRef; + +#[test] +fn test_hash_eq_ignore_span_expr_ref() { + use swc_ecma_ast::*; + + fn expr_ref<'a>(expr_ref: &'a Expr) -> HashEqIgnoreSpanExprRef<'a> { + HashEqIgnoreSpanExprRef(expr_ref) + } + + testing::run_test(false, |_cm, _handler| { + let dummy_sp = DUMMY_SP; + let meaningful_sp = dummy_sp.apply_mark(Mark::new()); + + let meaningful_ident_expr = Expr::Ident(Ident::new("foo".into(), meaningful_sp)); + let dummy_ident_expr = Expr::Ident(Ident::new("foo".into(), dummy_sp)); + + let meaningful_member_expr = member_expr!(meaningful_sp, foo.bar); + let dummy_member_expr = member_expr!(dummy_sp, foo.bar); + + let meaningful_null_expr = quote_expr!(meaningful_sp, null); + let dummy_null_expr = quote_expr!(dummy_sp, null); + + assert_eq!( + expr_ref(&meaningful_ident_expr), + expr_ref(&dummy_ident_expr) + ); + + let mut set = FxHashSet::from_iter([ + expr_ref(&meaningful_ident_expr), + expr_ref(&meaningful_member_expr), + expr_ref(&meaningful_null_expr), + ]); + + assert!(set.contains(&expr_ref(&dummy_ident_expr))); + assert!(set.contains(&expr_ref(&dummy_member_expr))); + assert!(set.contains(&expr_ref(&dummy_null_expr))); + + set.insert(expr_ref(&dummy_ident_expr)); + set.insert(expr_ref(&dummy_member_expr)); + set.insert(expr_ref(&dummy_null_expr)); + assert_eq!(set.len(), 3); + + Ok(()) + }) + .unwrap(); +} From 8af93ae1fca8fcd32ed906a0d2209a76596954e3 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 19:14:15 +0800 Subject: [PATCH 07/14] Tests --- crates/swc_ecma_minifier/src/metadata/tests.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/tests.rs b/crates/swc_ecma_minifier/src/metadata/tests.rs index 7e56a7849e23..07cdeff0d1ea 100644 --- a/crates/swc_ecma_minifier/src/metadata/tests.rs +++ b/crates/swc_ecma_minifier/src/metadata/tests.rs @@ -159,8 +159,6 @@ // assert_standalone("export default function f(module, exports) {}", 0); // } -use std::hash::Hash; - use rustc_hash::FxHashSet; use swc_common::{Mark, DUMMY_SP}; use swc_ecma_utils::{member_expr, quote_expr}; @@ -171,7 +169,7 @@ use super::HashEqIgnoreSpanExprRef; fn test_hash_eq_ignore_span_expr_ref() { use swc_ecma_ast::*; - fn expr_ref<'a>(expr_ref: &'a Expr) -> HashEqIgnoreSpanExprRef<'a> { + fn expr_ref(expr_ref: &Expr) -> HashEqIgnoreSpanExprRef { HashEqIgnoreSpanExprRef(expr_ref) } @@ -188,6 +186,7 @@ fn test_hash_eq_ignore_span_expr_ref() { let meaningful_null_expr = quote_expr!(meaningful_sp, null); let dummy_null_expr = quote_expr!(dummy_sp, null); + // Should equal ignoring span and syntax context assert_eq!( expr_ref(&meaningful_ident_expr), expr_ref(&dummy_ident_expr) @@ -199,6 +198,7 @@ fn test_hash_eq_ignore_span_expr_ref() { expr_ref(&meaningful_null_expr), ]); + // Should produce the same hash value ignoring span and syntax context assert!(set.contains(&expr_ref(&dummy_ident_expr))); assert!(set.contains(&expr_ref(&dummy_member_expr))); assert!(set.contains(&expr_ref(&dummy_null_expr))); @@ -208,6 +208,12 @@ fn test_hash_eq_ignore_span_expr_ref() { set.insert(expr_ref(&dummy_null_expr)); assert_eq!(set.len(), 3); + // Should not equal ignoring span and syntax context + let dummy_ident_expr = Expr::Ident(Ident::new("baz".into(), dummy_sp)); + let dummy_member_expr = member_expr!(dummy_sp, baz.bar); + assert!(!set.contains(&expr_ref(&dummy_ident_expr))); + assert!(!set.contains(&expr_ref(&dummy_member_expr))); + Ok(()) }) .unwrap(); From 7aaad6a96e871fa03909b2d97b7e9a64e26c7bd5 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 20:41:14 +0800 Subject: [PATCH 08/14] More tests --- .../swc_ecma_minifier/src/metadata/tests.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/tests.rs b/crates/swc_ecma_minifier/src/metadata/tests.rs index 07cdeff0d1ea..3b69fdedefed 100644 --- a/crates/swc_ecma_minifier/src/metadata/tests.rs +++ b/crates/swc_ecma_minifier/src/metadata/tests.rs @@ -160,7 +160,7 @@ // } use rustc_hash::FxHashSet; -use swc_common::{Mark, DUMMY_SP}; +use swc_common::{util::take::Take, Mark, DUMMY_SP}; use swc_ecma_utils::{member_expr, quote_expr}; use super::HashEqIgnoreSpanExprRef; @@ -186,33 +186,50 @@ fn test_hash_eq_ignore_span_expr_ref() { let meaningful_null_expr = quote_expr!(meaningful_sp, null); let dummy_null_expr = quote_expr!(dummy_sp, null); + let meaningful_array_expr = Box::new(Expr::Array(ArrayLit { + span: meaningful_sp, + elems: Default::default(), + })); + + let dummy_array_expr = Box::new(Expr::Array(ArrayLit::dummy())); + // Should equal ignoring span and syntax context assert_eq!( expr_ref(&meaningful_ident_expr), expr_ref(&dummy_ident_expr) ); + assert_eq!( + expr_ref(&meaningful_array_expr), + expr_ref(&dummy_array_expr) + ); + let mut set = FxHashSet::from_iter([ expr_ref(&meaningful_ident_expr), expr_ref(&meaningful_member_expr), expr_ref(&meaningful_null_expr), + expr_ref(&meaningful_array_expr), ]); // Should produce the same hash value ignoring span and syntax context assert!(set.contains(&expr_ref(&dummy_ident_expr))); assert!(set.contains(&expr_ref(&dummy_member_expr))); assert!(set.contains(&expr_ref(&dummy_null_expr))); + assert!(set.contains(&expr_ref(&dummy_array_expr))); set.insert(expr_ref(&dummy_ident_expr)); set.insert(expr_ref(&dummy_member_expr)); set.insert(expr_ref(&dummy_null_expr)); - assert_eq!(set.len(), 3); + set.insert(expr_ref(&dummy_array_expr)); + assert_eq!(set.len(), 4); // Should not equal ignoring span and syntax context let dummy_ident_expr = Expr::Ident(Ident::new("baz".into(), dummy_sp)); let dummy_member_expr = member_expr!(dummy_sp, baz.bar); + let dummy_arrow_expr = Box::new(Expr::Arrow(ArrowExpr::dummy())); assert!(!set.contains(&expr_ref(&dummy_ident_expr))); assert!(!set.contains(&expr_ref(&dummy_member_expr))); + assert!(!set.contains(&expr_ref(&dummy_arrow_expr))); Ok(()) }) From 2425173fea0f5d3149e15c9e502ffa090ab99b84 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 21:22:08 +0800 Subject: [PATCH 09/14] Make PURE_FUNC_LIST --- crates/swc_ecma_minifier/src/compress/mod.rs | 1 + .../src/compress/pure_exprs.rs | 822 ++++++++++++++++++ 2 files changed, 823 insertions(+) create mode 100644 crates/swc_ecma_minifier/src/compress/pure_exprs.rs diff --git a/crates/swc_ecma_minifier/src/compress/mod.rs b/crates/swc_ecma_minifier/src/compress/mod.rs index 9fb00fd33938..fd36d7d13b7f 100644 --- a/crates/swc_ecma_minifier/src/compress/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/mod.rs @@ -36,6 +36,7 @@ use crate::{ mod hoist_decls; mod optimize; mod pure; +mod pure_exprs; mod util; pub(crate) fn compressor<'a, M>( diff --git a/crates/swc_ecma_minifier/src/compress/pure_exprs.rs b/crates/swc_ecma_minifier/src/compress/pure_exprs.rs new file mode 100644 index 000000000000..5c520cfd6bae --- /dev/null +++ b/crates/swc_ecma_minifier/src/compress/pure_exprs.rs @@ -0,0 +1,822 @@ +use once_cell::sync::Lazy; +use swc_common::DUMMY_SP; +use swc_ecma_ast::{Expr, Ident}; +use swc_ecma_utils::{member_expr, quote_ident}; + +macro_rules! dummy_ident_expr { + ($s:ident) => { + Box::new(Expr::Ident(quote_ident!(DUMMY_SP, stringify!($s)))) + }; +} + +pub(super) static PURE_FUNC_LIST: Lazy>> = Lazy::new(|| preset_of_pure_func()); + +// The list is copied from https://github.com/evanw/esbuild/blob/5fe21253ee75fb4c5ea395a0877b2a5ab51c3575/internal/config/globals.go +fn preset_of_pure_func() -> Vec> { + vec![ + // These global identifiers should exist in all JavaScript environments. This + // deliberately omits "NaN", "Infinity", and "undefined" because these are + // treated as automatically-inlined constants instead of identifiers. + dummy_ident_expr!(Array), + dummy_ident_expr!(Boolean), + dummy_ident_expr!(Function), + dummy_ident_expr!(Math), + dummy_ident_expr!(Number), + dummy_ident_expr!(Object), + dummy_ident_expr!(RegExp), + dummy_ident_expr!(String), + // Object: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods + member_expr!(DUMMY_SP, Object.assign), + member_expr!(DUMMY_SP, Object.create), + member_expr!(DUMMY_SP, Object.defineProperties), + member_expr!(DUMMY_SP, Object.defineProperty), + member_expr!(DUMMY_SP, Object.entries), + member_expr!(DUMMY_SP, Object.freeze), + member_expr!(DUMMY_SP, Object.fromEntries), + member_expr!(DUMMY_SP, Object.getOwnPropertyDescriptor), + member_expr!(DUMMY_SP, Object.getOwnPropertyDescriptors), + member_expr!(DUMMY_SP, Object.getOwnPropertyNames), + member_expr!(DUMMY_SP, Object.getOwnPropertySymbols), + member_expr!(DUMMY_SP, Object.getPrototypeOf), + member_expr!(DUMMY_SP, Object.is), + member_expr!(DUMMY_SP, Object.isExtensible), + member_expr!(DUMMY_SP, Object.isFrozen), + member_expr!(DUMMY_SP, Object.isSealed), + member_expr!(DUMMY_SP, Object.keys), + member_expr!(DUMMY_SP, Object.preventExtensions), + member_expr!(DUMMY_SP, Object.seal), + member_expr!(DUMMY_SP, Object.setPrototypeOf), + member_expr!(DUMMY_SP, Object.values), + // Object: Instance methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Instance_methods + member_expr!(DUMMY_SP, Object.prototype.__defineGetter__), + member_expr!(DUMMY_SP, Object.prototype.__defineSetter__), + member_expr!(DUMMY_SP, Object.prototype.__lookupGetter__), + member_expr!(DUMMY_SP, Object.prototype.__lookupSetter__), + member_expr!(DUMMY_SP, Object.prototype.hasOwnProperty), + member_expr!(DUMMY_SP, Object.prototype.isPrototypeOf), + member_expr!(DUMMY_SP, Object.prototype.propertyIsEnumerable), + member_expr!(DUMMY_SP, Object.prototype.toLocaleString), + member_expr!(DUMMY_SP, Object.prototype.toString), + member_expr!(DUMMY_SP, Object.prototype.unwatch), + member_expr!(DUMMY_SP, Object.prototype.valueOf), + member_expr!(DUMMY_SP, Object.prototype.watch), + // Symbol: Static properties + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties + member_expr!(DUMMY_SP, Symbol.asyncIterator), + member_expr!(DUMMY_SP, Symbol.hasInstance), + member_expr!(DUMMY_SP, Symbol.isConcatSpreadable), + member_expr!(DUMMY_SP, Symbol.iterator), + member_expr!(DUMMY_SP, Symbol.match), + member_expr!(DUMMY_SP, Symbol.matchAll), + member_expr!(DUMMY_SP, Symbol.replace), + member_expr!(DUMMY_SP, Symbol.search), + member_expr!(DUMMY_SP, Symbol.species), + member_expr!(DUMMY_SP, Symbol.split), + member_expr!(DUMMY_SP, Symbol.toPrimitive), + member_expr!(DUMMY_SP, Symbol.toStringTag), + member_expr!(DUMMY_SP, Symbol.unscopables), + // Math: Static properties + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_properties + member_expr!(DUMMY_SP, Math.E), + member_expr!(DUMMY_SP, Math.LN10), + member_expr!(DUMMY_SP, Math.LN2), + member_expr!(DUMMY_SP, Math.LOG10E), + member_expr!(DUMMY_SP, Math.LOG2E), + member_expr!(DUMMY_SP, Math.PI), + member_expr!(DUMMY_SP, Math.SQRT1_2), + member_expr!(DUMMY_SP, Math.SQRT2), + // Math: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_methods + member_expr!(DUMMY_SP, Math.abs), + member_expr!(DUMMY_SP, Math.acos), + member_expr!(DUMMY_SP, Math.acosh), + member_expr!(DUMMY_SP, Math.asin), + member_expr!(DUMMY_SP, Math.asinh), + member_expr!(DUMMY_SP, Math.atan), + member_expr!(DUMMY_SP, Math.atan2), + member_expr!(DUMMY_SP, Math.atanh), + member_expr!(DUMMY_SP, Math.cbrt), + member_expr!(DUMMY_SP, Math.ceil), + member_expr!(DUMMY_SP, Math.clz32), + member_expr!(DUMMY_SP, Math.cos), + member_expr!(DUMMY_SP, Math.cosh), + member_expr!(DUMMY_SP, Math.exp), + member_expr!(DUMMY_SP, Math.expm1), + member_expr!(DUMMY_SP, Math.floor), + member_expr!(DUMMY_SP, Math.fround), + member_expr!(DUMMY_SP, Math.hypot), + member_expr!(DUMMY_SP, Math.imul), + member_expr!(DUMMY_SP, Math.log), + member_expr!(DUMMY_SP, Math.log10), + member_expr!(DUMMY_SP, Math.log1p), + member_expr!(DUMMY_SP, Math.log2), + member_expr!(DUMMY_SP, Math.max), + member_expr!(DUMMY_SP, Math.min), + member_expr!(DUMMY_SP, Math.pow), + member_expr!(DUMMY_SP, Math.random), + member_expr!(DUMMY_SP, Math.round), + member_expr!(DUMMY_SP, Math.sign), + member_expr!(DUMMY_SP, Math.sin), + member_expr!(DUMMY_SP, Math.sinh), + member_expr!(DUMMY_SP, Math.sqrt), + member_expr!(DUMMY_SP, Math.tan), + member_expr!(DUMMY_SP, Math.tanh), + member_expr!(DUMMY_SP, Math.trunc), + // Reflect: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods + member_expr!(DUMMY_SP, Reflect.apply), + member_expr!(DUMMY_SP, Reflect.construct), + member_expr!(DUMMY_SP, Reflect.defineProperty), + member_expr!(DUMMY_SP, Reflect.deleteProperty), + member_expr!(DUMMY_SP, Reflect.get), + member_expr!(DUMMY_SP, Reflect.getOwnPropertyDescriptor), + member_expr!(DUMMY_SP, Reflect.getPrototypeOf), + member_expr!(DUMMY_SP, Reflect.has), + member_expr!(DUMMY_SP, Reflect.isExtensible), + member_expr!(DUMMY_SP, Reflect.ownKeys), + member_expr!(DUMMY_SP, Reflect.preventExtensions), + member_expr!(DUMMY_SP, Reflect.set), + member_expr!(DUMMY_SP, Reflect.setPrototypeOf), + // JSON: Static Methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON#static_methods + member_expr!(DUMMY_SP, JSON.parse), + member_expr!(DUMMY_SP, JSON.stringify), + // Other globals present in both the browser and node (except "eval" because + // it has special behavior) + dummy_ident_expr!(AbortController), + dummy_ident_expr!(AbortSignal), + dummy_ident_expr!(AggregateError), + dummy_ident_expr!(ArrayBuffer), + dummy_ident_expr!(BigInt), + dummy_ident_expr!(DataView), + dummy_ident_expr!(Date), + dummy_ident_expr!(Error), + dummy_ident_expr!(EvalError), + dummy_ident_expr!(Event), + dummy_ident_expr!(EventTarget), + dummy_ident_expr!(Float32Array), + dummy_ident_expr!(Float64Array), + dummy_ident_expr!(Int16Array), + dummy_ident_expr!(Int32Array), + dummy_ident_expr!(Int8Array), + dummy_ident_expr!(Intl), + dummy_ident_expr!(JSON), + dummy_ident_expr!(Map), + dummy_ident_expr!(MessageChannel), + dummy_ident_expr!(MessageEvent), + dummy_ident_expr!(MessagePort), + dummy_ident_expr!(Promise), + dummy_ident_expr!(Proxy), + dummy_ident_expr!(RangeError), + dummy_ident_expr!(ReferenceError), + dummy_ident_expr!(Reflect), + dummy_ident_expr!(Set), + dummy_ident_expr!(Symbol), + dummy_ident_expr!(SyntaxError), + dummy_ident_expr!(TextDecoder), + dummy_ident_expr!(TextEncoder), + dummy_ident_expr!(TypeError), + dummy_ident_expr!(URIError), + dummy_ident_expr!(URL), + dummy_ident_expr!(URLSearchParams), + dummy_ident_expr!(Uint16Array), + dummy_ident_expr!(Uint32Array), + dummy_ident_expr!(Uint8Array), + dummy_ident_expr!(Uint8ClampedArray), + dummy_ident_expr!(WeakMap), + dummy_ident_expr!(WeakSet), + dummy_ident_expr!(WebAssembly), + dummy_ident_expr!(clearInterval), + dummy_ident_expr!(clearTimeout), + dummy_ident_expr!(console), + dummy_ident_expr!(decodeURI), + dummy_ident_expr!(decodeURIComponent), + dummy_ident_expr!(encodeURI), + dummy_ident_expr!(encodeURIComponent), + dummy_ident_expr!(escape), + dummy_ident_expr!(globalThis), + dummy_ident_expr!(isFinite), + dummy_ident_expr!(isNaN), + dummy_ident_expr!(parseFloat), + dummy_ident_expr!(parseInt), + dummy_ident_expr!(queueMicrotask), + dummy_ident_expr!(setInterval), + dummy_ident_expr!(setTimeout), + dummy_ident_expr!(unescape), + // Console method references are assumed to have no side effects + // https://developer.mozilla.org/en-US/docs/Web/API/console + member_expr!(DUMMY_SP, console.assert), + member_expr!(DUMMY_SP, console.clear), + member_expr!(DUMMY_SP, console.count), + member_expr!(DUMMY_SP, console.countReset), + member_expr!(DUMMY_SP, console.debug), + member_expr!(DUMMY_SP, console.dir), + member_expr!(DUMMY_SP, console.dirxml), + member_expr!(DUMMY_SP, console.error), + member_expr!(DUMMY_SP, console.group), + member_expr!(DUMMY_SP, console.groupCollapsed), + member_expr!(DUMMY_SP, console.groupEnd), + member_expr!(DUMMY_SP, console.info), + member_expr!(DUMMY_SP, console.log), + member_expr!(DUMMY_SP, console.table), + member_expr!(DUMMY_SP, console.time), + member_expr!(DUMMY_SP, console.timeEnd), + member_expr!(DUMMY_SP, console.timeLog), + member_expr!(DUMMY_SP, console.trace), + member_expr!(DUMMY_SP, console.warn), + // CSSOM APIs + dummy_ident_expr!(CSSAnimation), + dummy_ident_expr!(CSSFontFaceRule), + dummy_ident_expr!(CSSImportRule), + dummy_ident_expr!(CSSKeyframeRule), + dummy_ident_expr!(CSSKeyframesRule), + dummy_ident_expr!(CSSMediaRule), + dummy_ident_expr!(CSSNamespaceRule), + dummy_ident_expr!(CSSPageRule), + dummy_ident_expr!(CSSRule), + dummy_ident_expr!(CSSRuleList), + dummy_ident_expr!(CSSStyleDeclaration), + dummy_ident_expr!(CSSStyleRule), + dummy_ident_expr!(CSSStyleSheet), + dummy_ident_expr!(CSSSupportsRule), + dummy_ident_expr!(CSSTransition), + // SVG DOM + dummy_ident_expr!(SVGAElement), + dummy_ident_expr!(SVGAngle), + dummy_ident_expr!(SVGAnimateElement), + dummy_ident_expr!(SVGAnimateMotionElement), + dummy_ident_expr!(SVGAnimateTransformElement), + dummy_ident_expr!(SVGAnimatedAngle), + dummy_ident_expr!(SVGAnimatedBoolean), + dummy_ident_expr!(SVGAnimatedEnumeration), + dummy_ident_expr!(SVGAnimatedInteger), + dummy_ident_expr!(SVGAnimatedLength), + dummy_ident_expr!(SVGAnimatedLengthList), + dummy_ident_expr!(SVGAnimatedNumber), + dummy_ident_expr!(SVGAnimatedNumberList), + dummy_ident_expr!(SVGAnimatedPreserveAspectRatio), + dummy_ident_expr!(SVGAnimatedRect), + dummy_ident_expr!(SVGAnimatedString), + dummy_ident_expr!(SVGAnimatedTransformList), + dummy_ident_expr!(SVGAnimationElement), + dummy_ident_expr!(SVGCircleElement), + dummy_ident_expr!(SVGClipPathElement), + dummy_ident_expr!(SVGComponentTransferFunctionElement), + dummy_ident_expr!(SVGDefsElement), + dummy_ident_expr!(SVGDescElement), + dummy_ident_expr!(SVGElement), + dummy_ident_expr!(SVGEllipseElement), + dummy_ident_expr!(SVGFEBlendElement), + dummy_ident_expr!(SVGFEColorMatrixElement), + dummy_ident_expr!(SVGFEComponentTransferElement), + dummy_ident_expr!(SVGFECompositeElement), + dummy_ident_expr!(SVGFEConvolveMatrixElement), + dummy_ident_expr!(SVGFEDiffuseLightingElement), + dummy_ident_expr!(SVGFEDisplacementMapElement), + dummy_ident_expr!(SVGFEDistantLightElement), + dummy_ident_expr!(SVGFEDropShadowElement), + dummy_ident_expr!(SVGFEFloodElement), + dummy_ident_expr!(SVGFEFuncAElement), + dummy_ident_expr!(SVGFEFuncBElement), + dummy_ident_expr!(SVGFEFuncGElement), + dummy_ident_expr!(SVGFEFuncRElement), + dummy_ident_expr!(SVGFEGaussianBlurElement), + dummy_ident_expr!(SVGFEImageElement), + dummy_ident_expr!(SVGFEMergeElement), + dummy_ident_expr!(SVGFEMergeNodeElement), + dummy_ident_expr!(SVGFEMorphologyElement), + dummy_ident_expr!(SVGFEOffsetElement), + dummy_ident_expr!(SVGFEPointLightElement), + dummy_ident_expr!(SVGFESpecularLightingElement), + dummy_ident_expr!(SVGFESpotLightElement), + dummy_ident_expr!(SVGFETileElement), + dummy_ident_expr!(SVGFETurbulenceElement), + dummy_ident_expr!(SVGFilterElement), + dummy_ident_expr!(SVGForeignObjectElement), + dummy_ident_expr!(SVGGElement), + dummy_ident_expr!(SVGGeometryElement), + dummy_ident_expr!(SVGGradientElement), + dummy_ident_expr!(SVGGraphicsElement), + dummy_ident_expr!(SVGImageElement), + dummy_ident_expr!(SVGLength), + dummy_ident_expr!(SVGLengthList), + dummy_ident_expr!(SVGLineElement), + dummy_ident_expr!(SVGLinearGradientElement), + dummy_ident_expr!(SVGMPathElement), + dummy_ident_expr!(SVGMarkerElement), + dummy_ident_expr!(SVGMaskElement), + dummy_ident_expr!(SVGMatrix), + dummy_ident_expr!(SVGMetadataElement), + dummy_ident_expr!(SVGNumber), + dummy_ident_expr!(SVGNumberList), + dummy_ident_expr!(SVGPathElement), + dummy_ident_expr!(SVGPatternElement), + dummy_ident_expr!(SVGPoint), + dummy_ident_expr!(SVGPointList), + dummy_ident_expr!(SVGPolygonElement), + dummy_ident_expr!(SVGPolylineElement), + dummy_ident_expr!(SVGPreserveAspectRatio), + dummy_ident_expr!(SVGRadialGradientElement), + dummy_ident_expr!(SVGRect), + dummy_ident_expr!(SVGRectElement), + dummy_ident_expr!(SVGSVGElement), + dummy_ident_expr!(SVGScriptElement), + dummy_ident_expr!(SVGSetElement), + dummy_ident_expr!(SVGStopElement), + dummy_ident_expr!(SVGStringList), + dummy_ident_expr!(SVGStyleElement), + dummy_ident_expr!(SVGSwitchElement), + dummy_ident_expr!(SVGSymbolElement), + dummy_ident_expr!(SVGTSpanElement), + dummy_ident_expr!(SVGTextContentElement), + dummy_ident_expr!(SVGTextElement), + dummy_ident_expr!(SVGTextPathElement), + dummy_ident_expr!(SVGTextPositioningElement), + dummy_ident_expr!(SVGTitleElement), + dummy_ident_expr!(SVGTransform), + dummy_ident_expr!(SVGTransformList), + dummy_ident_expr!(SVGUnitTypes), + dummy_ident_expr!(SVGUseElement), + dummy_ident_expr!(SVGViewElement), + // Other browser APIs + // + // This list contains all globals present in modern versions of Chrome, Safari, + // and Firefox except for the following properties, since they have a side effect + // of triggering layout (https://gist.github.com/paulirish/5d52fb081b3570c81e3a): + // + // - scrollX + // - scrollY + // - innerWidth + // - innerHeight + // - pageXOffset + // - pageYOffset + // + // The following globals have also been removed since they sometimes throw an + // exception when accessed, which is a side effect (for more information see + // https://stackoverflow.com/a/33047477): + // + // - localStorage + // - sessionStorage + dummy_ident_expr!(AnalyserNode), + dummy_ident_expr!(Animation), + dummy_ident_expr!(AnimationEffect), + dummy_ident_expr!(AnimationEvent), + dummy_ident_expr!(AnimationPlaybackEvent), + dummy_ident_expr!(AnimationTimeline), + dummy_ident_expr!(Attr), + dummy_ident_expr!(Audio), + dummy_ident_expr!(AudioBuffer), + dummy_ident_expr!(AudioBufferSourceNode), + dummy_ident_expr!(AudioDestinationNode), + dummy_ident_expr!(AudioListener), + dummy_ident_expr!(AudioNode), + dummy_ident_expr!(AudioParam), + dummy_ident_expr!(AudioProcessingEvent), + dummy_ident_expr!(AudioScheduledSourceNode), + dummy_ident_expr!(BarProp), + dummy_ident_expr!(BeforeUnloadEvent), + dummy_ident_expr!(BiquadFilterNode), + dummy_ident_expr!(Blob), + dummy_ident_expr!(BlobEvent), + dummy_ident_expr!(ByteLengthQueuingStrategy), + dummy_ident_expr!(CDATASection), + dummy_ident_expr!(CSS), + dummy_ident_expr!(CanvasGradient), + dummy_ident_expr!(CanvasPattern), + dummy_ident_expr!(CanvasRenderingContext2D), + dummy_ident_expr!(ChannelMergerNode), + dummy_ident_expr!(ChannelSplitterNode), + dummy_ident_expr!(CharacterData), + dummy_ident_expr!(ClipboardEvent), + dummy_ident_expr!(CloseEvent), + dummy_ident_expr!(Comment), + dummy_ident_expr!(CompositionEvent), + dummy_ident_expr!(ConvolverNode), + dummy_ident_expr!(CountQueuingStrategy), + dummy_ident_expr!(Crypto), + dummy_ident_expr!(CustomElementRegistry), + dummy_ident_expr!(CustomEvent), + dummy_ident_expr!(DOMException), + dummy_ident_expr!(DOMImplementation), + dummy_ident_expr!(DOMMatrix), + dummy_ident_expr!(DOMMatrixReadOnly), + dummy_ident_expr!(DOMParser), + dummy_ident_expr!(DOMPoint), + dummy_ident_expr!(DOMPointReadOnly), + dummy_ident_expr!(DOMQuad), + dummy_ident_expr!(DOMRect), + dummy_ident_expr!(DOMRectList), + dummy_ident_expr!(DOMRectReadOnly), + dummy_ident_expr!(DOMStringList), + dummy_ident_expr!(DOMStringMap), + dummy_ident_expr!(DOMTokenList), + dummy_ident_expr!(DataTransfer), + dummy_ident_expr!(DataTransferItem), + dummy_ident_expr!(DataTransferItemList), + dummy_ident_expr!(DelayNode), + dummy_ident_expr!(Document), + dummy_ident_expr!(DocumentFragment), + dummy_ident_expr!(DocumentTimeline), + dummy_ident_expr!(DocumentType), + dummy_ident_expr!(DragEvent), + dummy_ident_expr!(DynamicsCompressorNode), + dummy_ident_expr!(Element), + dummy_ident_expr!(ErrorEvent), + dummy_ident_expr!(EventSource), + dummy_ident_expr!(File), + dummy_ident_expr!(FileList), + dummy_ident_expr!(FileReader), + dummy_ident_expr!(FocusEvent), + dummy_ident_expr!(FontFace), + dummy_ident_expr!(FormData), + dummy_ident_expr!(GainNode), + dummy_ident_expr!(Gamepad), + dummy_ident_expr!(GamepadButton), + dummy_ident_expr!(GamepadEvent), + dummy_ident_expr!(Geolocation), + dummy_ident_expr!(GeolocationPositionError), + dummy_ident_expr!(HTMLAllCollection), + dummy_ident_expr!(HTMLAnchorElement), + dummy_ident_expr!(HTMLAreaElement), + dummy_ident_expr!(HTMLAudioElement), + dummy_ident_expr!(HTMLBRElement), + dummy_ident_expr!(HTMLBaseElement), + dummy_ident_expr!(HTMLBodyElement), + dummy_ident_expr!(HTMLButtonElement), + dummy_ident_expr!(HTMLCanvasElement), + dummy_ident_expr!(HTMLCollection), + dummy_ident_expr!(HTMLDListElement), + dummy_ident_expr!(HTMLDataElement), + dummy_ident_expr!(HTMLDataListElement), + dummy_ident_expr!(HTMLDetailsElement), + dummy_ident_expr!(HTMLDirectoryElement), + dummy_ident_expr!(HTMLDivElement), + dummy_ident_expr!(HTMLDocument), + dummy_ident_expr!(HTMLElement), + dummy_ident_expr!(HTMLEmbedElement), + dummy_ident_expr!(HTMLFieldSetElement), + dummy_ident_expr!(HTMLFontElement), + dummy_ident_expr!(HTMLFormControlsCollection), + dummy_ident_expr!(HTMLFormElement), + dummy_ident_expr!(HTMLFrameElement), + dummy_ident_expr!(HTMLFrameSetElement), + dummy_ident_expr!(HTMLHRElement), + dummy_ident_expr!(HTMLHeadElement), + dummy_ident_expr!(HTMLHeadingElement), + dummy_ident_expr!(HTMLHtmlElement), + dummy_ident_expr!(HTMLIFrameElement), + dummy_ident_expr!(HTMLImageElement), + dummy_ident_expr!(HTMLInputElement), + dummy_ident_expr!(HTMLLIElement), + dummy_ident_expr!(HTMLLabelElement), + dummy_ident_expr!(HTMLLegendElement), + dummy_ident_expr!(HTMLLinkElement), + dummy_ident_expr!(HTMLMapElement), + dummy_ident_expr!(HTMLMarqueeElement), + dummy_ident_expr!(HTMLMediaElement), + dummy_ident_expr!(HTMLMenuElement), + dummy_ident_expr!(HTMLMetaElement), + dummy_ident_expr!(HTMLMeterElement), + dummy_ident_expr!(HTMLModElement), + dummy_ident_expr!(HTMLOListElement), + dummy_ident_expr!(HTMLObjectElement), + dummy_ident_expr!(HTMLOptGroupElement), + dummy_ident_expr!(HTMLOptionElement), + dummy_ident_expr!(HTMLOptionsCollection), + dummy_ident_expr!(HTMLOutputElement), + dummy_ident_expr!(HTMLParagraphElement), + dummy_ident_expr!(HTMLParamElement), + dummy_ident_expr!(HTMLPictureElement), + dummy_ident_expr!(HTMLPreElement), + dummy_ident_expr!(HTMLProgressElement), + dummy_ident_expr!(HTMLQuoteElement), + dummy_ident_expr!(HTMLScriptElement), + dummy_ident_expr!(HTMLSelectElement), + dummy_ident_expr!(HTMLSlotElement), + dummy_ident_expr!(HTMLSourceElement), + dummy_ident_expr!(HTMLSpanElement), + dummy_ident_expr!(HTMLStyleElement), + dummy_ident_expr!(HTMLTableCaptionElement), + dummy_ident_expr!(HTMLTableCellElement), + dummy_ident_expr!(HTMLTableColElement), + dummy_ident_expr!(HTMLTableElement), + dummy_ident_expr!(HTMLTableRowElement), + dummy_ident_expr!(HTMLTableSectionElement), + dummy_ident_expr!(HTMLTemplateElement), + dummy_ident_expr!(HTMLTextAreaElement), + dummy_ident_expr!(HTMLTimeElement), + dummy_ident_expr!(HTMLTitleElement), + dummy_ident_expr!(HTMLTrackElement), + dummy_ident_expr!(HTMLUListElement), + dummy_ident_expr!(HTMLUnknownElement), + dummy_ident_expr!(HTMLVideoElement), + dummy_ident_expr!(HashChangeEvent), + dummy_ident_expr!(Headers), + dummy_ident_expr!(History), + dummy_ident_expr!(IDBCursor), + dummy_ident_expr!(IDBCursorWithValue), + dummy_ident_expr!(IDBDatabase), + dummy_ident_expr!(IDBFactory), + dummy_ident_expr!(IDBIndex), + dummy_ident_expr!(IDBKeyRange), + dummy_ident_expr!(IDBObjectStore), + dummy_ident_expr!(IDBOpenDBRequest), + dummy_ident_expr!(IDBRequest), + dummy_ident_expr!(IDBTransaction), + dummy_ident_expr!(IDBVersionChangeEvent), + dummy_ident_expr!(Image), + dummy_ident_expr!(ImageData), + dummy_ident_expr!(InputEvent), + dummy_ident_expr!(IntersectionObserver), + dummy_ident_expr!(IntersectionObserverEntry), + dummy_ident_expr!(KeyboardEvent), + dummy_ident_expr!(KeyframeEffect), + dummy_ident_expr!(Location), + dummy_ident_expr!(MediaCapabilities), + dummy_ident_expr!(MediaElementAudioSourceNode), + dummy_ident_expr!(MediaEncryptedEvent), + dummy_ident_expr!(MediaError), + dummy_ident_expr!(MediaList), + dummy_ident_expr!(MediaQueryList), + dummy_ident_expr!(MediaQueryListEvent), + dummy_ident_expr!(MediaRecorder), + dummy_ident_expr!(MediaSource), + dummy_ident_expr!(MediaStream), + dummy_ident_expr!(MediaStreamAudioDestinationNode), + dummy_ident_expr!(MediaStreamAudioSourceNode), + dummy_ident_expr!(MediaStreamTrack), + dummy_ident_expr!(MediaStreamTrackEvent), + dummy_ident_expr!(MimeType), + dummy_ident_expr!(MimeTypeArray), + dummy_ident_expr!(MouseEvent), + dummy_ident_expr!(MutationEvent), + dummy_ident_expr!(MutationObserver), + dummy_ident_expr!(MutationRecord), + dummy_ident_expr!(NamedNodeMap), + dummy_ident_expr!(Navigator), + dummy_ident_expr!(Node), + dummy_ident_expr!(NodeFilter), + dummy_ident_expr!(NodeIterator), + dummy_ident_expr!(NodeList), + dummy_ident_expr!(Notification), + dummy_ident_expr!(OfflineAudioCompletionEvent), + dummy_ident_expr!(Option), + dummy_ident_expr!(OscillatorNode), + dummy_ident_expr!(PageTransitionEvent), + dummy_ident_expr!(Path2D), + dummy_ident_expr!(Performance), + dummy_ident_expr!(PerformanceEntry), + dummy_ident_expr!(PerformanceMark), + dummy_ident_expr!(PerformanceMeasure), + dummy_ident_expr!(PerformanceNavigation), + dummy_ident_expr!(PerformanceObserver), + dummy_ident_expr!(PerformanceObserverEntryList), + dummy_ident_expr!(PerformanceResourceTiming), + dummy_ident_expr!(PerformanceTiming), + dummy_ident_expr!(PeriodicWave), + dummy_ident_expr!(Plugin), + dummy_ident_expr!(PluginArray), + dummy_ident_expr!(PointerEvent), + dummy_ident_expr!(PopStateEvent), + dummy_ident_expr!(ProcessingInstruction), + dummy_ident_expr!(ProgressEvent), + dummy_ident_expr!(PromiseRejectionEvent), + dummy_ident_expr!(RTCCertificate), + dummy_ident_expr!(RTCDTMFSender), + dummy_ident_expr!(RTCDTMFToneChangeEvent), + dummy_ident_expr!(RTCDataChannel), + dummy_ident_expr!(RTCDataChannelEvent), + dummy_ident_expr!(RTCIceCandidate), + dummy_ident_expr!(RTCPeerConnection), + dummy_ident_expr!(RTCPeerConnectionIceEvent), + dummy_ident_expr!(RTCRtpReceiver), + dummy_ident_expr!(RTCRtpSender), + dummy_ident_expr!(RTCRtpTransceiver), + dummy_ident_expr!(RTCSessionDescription), + dummy_ident_expr!(RTCStatsReport), + dummy_ident_expr!(RTCTrackEvent), + dummy_ident_expr!(RadioNodeList), + dummy_ident_expr!(Range), + dummy_ident_expr!(ReadableStream), + dummy_ident_expr!(Request), + dummy_ident_expr!(ResizeObserver), + dummy_ident_expr!(ResizeObserverEntry), + dummy_ident_expr!(Response), + dummy_ident_expr!(Screen), + dummy_ident_expr!(ScriptProcessorNode), + dummy_ident_expr!(SecurityPolicyViolationEvent), + dummy_ident_expr!(Selection), + dummy_ident_expr!(ShadowRoot), + dummy_ident_expr!(SourceBuffer), + dummy_ident_expr!(SourceBufferList), + dummy_ident_expr!(SpeechSynthesisEvent), + dummy_ident_expr!(SpeechSynthesisUtterance), + dummy_ident_expr!(StaticRange), + dummy_ident_expr!(Storage), + dummy_ident_expr!(StorageEvent), + dummy_ident_expr!(StyleSheet), + dummy_ident_expr!(StyleSheetList), + dummy_ident_expr!(Text), + dummy_ident_expr!(TextMetrics), + dummy_ident_expr!(TextTrack), + dummy_ident_expr!(TextTrackCue), + dummy_ident_expr!(TextTrackCueList), + dummy_ident_expr!(TextTrackList), + dummy_ident_expr!(TimeRanges), + dummy_ident_expr!(TrackEvent), + dummy_ident_expr!(TransitionEvent), + dummy_ident_expr!(TreeWalker), + dummy_ident_expr!(UIEvent), + dummy_ident_expr!(VTTCue), + dummy_ident_expr!(ValidityState), + dummy_ident_expr!(VisualViewport), + dummy_ident_expr!(WaveShaperNode), + dummy_ident_expr!(WebGLActiveInfo), + dummy_ident_expr!(WebGLBuffer), + dummy_ident_expr!(WebGLContextEvent), + dummy_ident_expr!(WebGLFramebuffer), + dummy_ident_expr!(WebGLProgram), + dummy_ident_expr!(WebGLQuery), + dummy_ident_expr!(WebGLRenderbuffer), + dummy_ident_expr!(WebGLRenderingContext), + dummy_ident_expr!(WebGLSampler), + dummy_ident_expr!(WebGLShader), + dummy_ident_expr!(WebGLShaderPrecisionFormat), + dummy_ident_expr!(WebGLSync), + dummy_ident_expr!(WebGLTexture), + dummy_ident_expr!(WebGLUniformLocation), + dummy_ident_expr!(WebKitCSSMatrix), + dummy_ident_expr!(WebSocket), + dummy_ident_expr!(WheelEvent), + dummy_ident_expr!(Window), + dummy_ident_expr!(Worker), + dummy_ident_expr!(XMLDocument), + dummy_ident_expr!(XMLHttpRequest), + dummy_ident_expr!(XMLHttpRequestEventTarget), + dummy_ident_expr!(XMLHttpRequestUpload), + dummy_ident_expr!(XMLSerializer), + dummy_ident_expr!(XPathEvaluator), + dummy_ident_expr!(XPathExpression), + dummy_ident_expr!(XPathResult), + dummy_ident_expr!(XSLTProcessor), + dummy_ident_expr!(alert), + dummy_ident_expr!(atob), + dummy_ident_expr!(blur), + dummy_ident_expr!(btoa), + dummy_ident_expr!(cancelAnimationFrame), + dummy_ident_expr!(captureEvents), + dummy_ident_expr!(close), + dummy_ident_expr!(closed), + dummy_ident_expr!(confirm), + dummy_ident_expr!(customElements), + dummy_ident_expr!(devicePixelRatio), + dummy_ident_expr!(document), + dummy_ident_expr!(event), + dummy_ident_expr!(fetch), + dummy_ident_expr!(find), + dummy_ident_expr!(focus), + dummy_ident_expr!(frameElement), + dummy_ident_expr!(frames), + dummy_ident_expr!(getComputedStyle), + dummy_ident_expr!(getSelection), + dummy_ident_expr!(history), + dummy_ident_expr!(indexedDB), + dummy_ident_expr!(isSecureContext), + dummy_ident_expr!(length), + dummy_ident_expr!(location), + dummy_ident_expr!(locationbar), + dummy_ident_expr!(matchMedia), + dummy_ident_expr!(menubar), + dummy_ident_expr!(moveBy), + dummy_ident_expr!(moveTo), + dummy_ident_expr!(name), + dummy_ident_expr!(navigator), + dummy_ident_expr!(onabort), + dummy_ident_expr!(onafterprint), + dummy_ident_expr!(onanimationend), + dummy_ident_expr!(onanimationiteration), + dummy_ident_expr!(onanimationstart), + dummy_ident_expr!(onbeforeprint), + dummy_ident_expr!(onbeforeunload), + dummy_ident_expr!(onblur), + dummy_ident_expr!(oncanplay), + dummy_ident_expr!(oncanplaythrough), + dummy_ident_expr!(onchange), + dummy_ident_expr!(onclick), + dummy_ident_expr!(oncontextmenu), + dummy_ident_expr!(oncuechange), + dummy_ident_expr!(ondblclick), + dummy_ident_expr!(ondrag), + dummy_ident_expr!(ondragend), + dummy_ident_expr!(ondragenter), + dummy_ident_expr!(ondragleave), + dummy_ident_expr!(ondragover), + dummy_ident_expr!(ondragstart), + dummy_ident_expr!(ondrop), + dummy_ident_expr!(ondurationchange), + dummy_ident_expr!(onemptied), + dummy_ident_expr!(onended), + dummy_ident_expr!(onerror), + dummy_ident_expr!(onfocus), + dummy_ident_expr!(ongotpointercapture), + dummy_ident_expr!(onhashchange), + dummy_ident_expr!(oninput), + dummy_ident_expr!(oninvalid), + dummy_ident_expr!(onkeydown), + dummy_ident_expr!(onkeypress), + dummy_ident_expr!(onkeyup), + dummy_ident_expr!(onlanguagechange), + dummy_ident_expr!(onload), + dummy_ident_expr!(onloadeddata), + dummy_ident_expr!(onloadedmetadata), + dummy_ident_expr!(onloadstart), + dummy_ident_expr!(onlostpointercapture), + dummy_ident_expr!(onmessage), + dummy_ident_expr!(onmousedown), + dummy_ident_expr!(onmouseenter), + dummy_ident_expr!(onmouseleave), + dummy_ident_expr!(onmousemove), + dummy_ident_expr!(onmouseout), + dummy_ident_expr!(onmouseover), + dummy_ident_expr!(onmouseup), + dummy_ident_expr!(onoffline), + dummy_ident_expr!(ononline), + dummy_ident_expr!(onpagehide), + dummy_ident_expr!(onpageshow), + dummy_ident_expr!(onpause), + dummy_ident_expr!(onplay), + dummy_ident_expr!(onplaying), + dummy_ident_expr!(onpointercancel), + dummy_ident_expr!(onpointerdown), + dummy_ident_expr!(onpointerenter), + dummy_ident_expr!(onpointerleave), + dummy_ident_expr!(onpointermove), + dummy_ident_expr!(onpointerout), + dummy_ident_expr!(onpointerover), + dummy_ident_expr!(onpointerup), + dummy_ident_expr!(onpopstate), + dummy_ident_expr!(onprogress), + dummy_ident_expr!(onratechange), + dummy_ident_expr!(onrejectionhandled), + dummy_ident_expr!(onreset), + dummy_ident_expr!(onresize), + dummy_ident_expr!(onscroll), + dummy_ident_expr!(onseeked), + dummy_ident_expr!(onseeking), + dummy_ident_expr!(onselect), + dummy_ident_expr!(onstalled), + dummy_ident_expr!(onstorage), + dummy_ident_expr!(onsubmit), + dummy_ident_expr!(onsuspend), + dummy_ident_expr!(ontimeupdate), + dummy_ident_expr!(ontoggle), + dummy_ident_expr!(ontransitioncancel), + dummy_ident_expr!(ontransitionend), + dummy_ident_expr!(ontransitionrun), + dummy_ident_expr!(ontransitionstart), + dummy_ident_expr!(onunhandledrejection), + dummy_ident_expr!(onunload), + dummy_ident_expr!(onvolumechange), + dummy_ident_expr!(onwaiting), + dummy_ident_expr!(onwebkitanimationend), + dummy_ident_expr!(onwebkitanimationiteration), + dummy_ident_expr!(onwebkitanimationstart), + dummy_ident_expr!(onwebkittransitionend), + dummy_ident_expr!(onwheel), + dummy_ident_expr!(open), + dummy_ident_expr!(opener), + dummy_ident_expr!(origin), + dummy_ident_expr!(outerHeight), + dummy_ident_expr!(outerWidth), + dummy_ident_expr!(parent), + dummy_ident_expr!(performance), + dummy_ident_expr!(personalbar), + dummy_ident_expr!(postMessage), + dummy_ident_expr!(print), + dummy_ident_expr!(prompt), + dummy_ident_expr!(releaseEvents), + dummy_ident_expr!(requestAnimationFrame), + dummy_ident_expr!(resizeBy), + dummy_ident_expr!(resizeTo), + dummy_ident_expr!(screen), + dummy_ident_expr!(screenLeft), + dummy_ident_expr!(screenTop), + dummy_ident_expr!(screenX), + dummy_ident_expr!(screenY), + dummy_ident_expr!(scroll), + dummy_ident_expr!(scrollBy), + dummy_ident_expr!(scrollTo), + dummy_ident_expr!(scrollbars), + dummy_ident_expr!(self), + dummy_ident_expr!(speechSynthesis), + dummy_ident_expr!(status), + dummy_ident_expr!(statusbar), + dummy_ident_expr!(stop), + dummy_ident_expr!(toolbar), + dummy_ident_expr!(top), + dummy_ident_expr!(webkitURL), + dummy_ident_expr!(window), + ] +} From 48d8da5556b2294d4dcd79fb1365e142c8423569 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 21:26:44 +0800 Subject: [PATCH 10/14] Impl --- crates/swc_ecma_minifier/src/compress/mod.rs | 1 - crates/swc_ecma_minifier/src/metadata/mod.rs | 9 +++++++++ .../src/{compress => metadata}/pure_exprs.rs | 0 3 files changed, 9 insertions(+), 1 deletion(-) rename crates/swc_ecma_minifier/src/{compress => metadata}/pure_exprs.rs (100%) diff --git a/crates/swc_ecma_minifier/src/compress/mod.rs b/crates/swc_ecma_minifier/src/compress/mod.rs index fd36d7d13b7f..9fb00fd33938 100644 --- a/crates/swc_ecma_minifier/src/compress/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/mod.rs @@ -36,7 +36,6 @@ use crate::{ mod hoist_decls; mod optimize; mod pure; -mod pure_exprs; mod util; pub(crate) fn compressor<'a, M>( diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 78006273a292..3fd73009f700 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -14,6 +14,8 @@ use swc_ecma_visit::{ use crate::option::CompressOptions; +mod pure_exprs; + #[derive(Debug, Eq)] struct HashEqIgnoreSpanExprRef<'a>(&'a Expr); @@ -55,10 +57,17 @@ pub(crate) fn info_marker<'a>( marks: Marks, // unresolved_mark: Mark, ) -> impl 'a + VisitMut { + let pristine_globals = options.map_or(false, |opts| opts.pristine_globals); + let pure_funcs = options.map(|options| { options .pure_funcs .iter() + .chain(if pristine_globals { + [].iter() + } else { + pure_exprs::PURE_FUNC_LIST.iter() + }) .map(|f| HashEqIgnoreSpanExprRef(f)) .collect() }); diff --git a/crates/swc_ecma_minifier/src/compress/pure_exprs.rs b/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs similarity index 100% rename from crates/swc_ecma_minifier/src/compress/pure_exprs.rs rename to crates/swc_ecma_minifier/src/metadata/pure_exprs.rs From 43164e051cfe58fe3de67684c279a1000959c7aa Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 21:37:13 +0800 Subject: [PATCH 11/14] Clippy --- crates/swc_ecma_minifier/src/metadata/pure_exprs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs b/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs index 5c520cfd6bae..50c4852737c0 100644 --- a/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs +++ b/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs @@ -1,6 +1,6 @@ use once_cell::sync::Lazy; use swc_common::DUMMY_SP; -use swc_ecma_ast::{Expr, Ident}; +use swc_ecma_ast::Expr; use swc_ecma_utils::{member_expr, quote_ident}; macro_rules! dummy_ident_expr { @@ -9,7 +9,7 @@ macro_rules! dummy_ident_expr { }; } -pub(super) static PURE_FUNC_LIST: Lazy>> = Lazy::new(|| preset_of_pure_func()); +pub(super) static PURE_FUNC_LIST: Lazy>> = Lazy::new(preset_of_pure_func); // The list is copied from https://github.com/evanw/esbuild/blob/5fe21253ee75fb4c5ea395a0877b2a5ab51c3575/internal/config/globals.go fn preset_of_pure_func() -> Vec> { From 1c3a70c33e820498e7c4276739c3aa137eccc716 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sat, 21 Jan 2023 22:16:51 +0800 Subject: [PATCH 12/14] Add tests --- crates/swc_ecma_minifier/src/metadata/mod.rs | 36 +++++++++++-------- .../tests/fixture/pr/6842/1/config.json | 7 ++++ .../tests/fixture/pr/6842/1/input.js | 21 +++++++++++ .../tests/fixture/pr/6842/1/output.js | 0 .../tests/fixture/pr/6842/2/config.json | 7 ++++ .../tests/fixture/pr/6842/2/input.js | 21 +++++++++++ .../tests/fixture/pr/6842/2/output.js | 21 +++++++++++ 7 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/1/config.json create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/1/input.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/1/output.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/2/config.json create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/2/input.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/pr/6842/2/output.js diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 3fd73009f700..a83b98c37c15 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -58,19 +58,23 @@ pub(crate) fn info_marker<'a>( // unresolved_mark: Mark, ) -> impl 'a + VisitMut { let pristine_globals = options.map_or(false, |opts| opts.pristine_globals); + let mut pure_funcs = options + .map(|opts| { + opts.pure_funcs + .iter() + .map(|expr| HashEqIgnoreSpanExprRef(expr)) + .collect::>() + }) + .unwrap_or_default(); + + if pristine_globals { + pure_funcs.extend( + pure_exprs::PURE_FUNC_LIST + .iter() + .map(|expr| HashEqIgnoreSpanExprRef(expr)), + ); + } - let pure_funcs = options.map(|options| { - options - .pure_funcs - .iter() - .chain(if pristine_globals { - [].iter() - } else { - pure_exprs::PURE_FUNC_LIST.iter() - }) - .map(|f| HashEqIgnoreSpanExprRef(f)) - .collect() - }); InfoMarker { options, comments, @@ -90,7 +94,7 @@ struct State { struct InfoMarker<'a> { #[allow(dead_code)] options: Option<&'a CompressOptions>, - pure_funcs: Option>>, + pure_funcs: FxHashSet>, comments: Option<&'a dyn Comments>, marks: Marks, // unresolved_mark: Mark, @@ -176,10 +180,12 @@ impl VisitMut for InfoMarker<'_> { if self.has_pure(n.span) { n.span = n.span.apply_mark(self.marks.pure); - } else if let Some(pure_fns) = &self.pure_funcs { + } + + if !self.pure_funcs.is_empty() { if let Callee::Expr(e) = &n.callee { // Check for pure_funcs - if pure_fns.contains(&HashEqIgnoreSpanExprRef(e)) { + if self.pure_funcs.contains(&HashEqIgnoreSpanExprRef(e)) { n.span = n.span.apply_mark(self.marks.pure); }; } diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/config.json b/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/config.json new file mode 100644 index 000000000000..6a0d52cf69f6 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/config.json @@ -0,0 +1,7 @@ +{ + "pristine_globals": true, + "unused": true, + "reduce_vars": true, + "side_effects": true, + "toplevel": true +} \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/input.js b/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/input.js new file mode 100644 index 000000000000..49b716fc7281 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/input.js @@ -0,0 +1,21 @@ +Object.assign() +Object.create() +Object.defineProperties() +Object.defineProperty() +Object.entries() +Object.freeze() +Object.fromEntries() +Object.getOwnPropertyDescriptor() +Object.getOwnPropertyDescriptors() +Object.getOwnPropertyNames() +Object.getOwnPropertySymbols() +Object.getPrototypeOf() +Object.is() +Object.isExtensible() +Object.isFrozen() +Object.isSealed() +Object.keys() +Object.preventExtensions() +Object.seal() +Object.setPrototypeOf() +Object.values() diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/output.js b/crates/swc_ecma_minifier/tests/fixture/pr/6842/1/output.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/config.json b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/config.json new file mode 100644 index 000000000000..129b4d4f0994 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/config.json @@ -0,0 +1,7 @@ +{ + "pristine_globals": false, + "unused": true, + "reduce_vars": true, + "side_effects": true, + "toplevel": true +} \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/input.js b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/input.js new file mode 100644 index 000000000000..49b716fc7281 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/input.js @@ -0,0 +1,21 @@ +Object.assign() +Object.create() +Object.defineProperties() +Object.defineProperty() +Object.entries() +Object.freeze() +Object.fromEntries() +Object.getOwnPropertyDescriptor() +Object.getOwnPropertyDescriptors() +Object.getOwnPropertyNames() +Object.getOwnPropertySymbols() +Object.getPrototypeOf() +Object.is() +Object.isExtensible() +Object.isFrozen() +Object.isSealed() +Object.keys() +Object.preventExtensions() +Object.seal() +Object.setPrototypeOf() +Object.values() diff --git a/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/output.js b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/output.js new file mode 100644 index 000000000000..f8871cecc133 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/pr/6842/2/output.js @@ -0,0 +1,21 @@ +Object.assign(); +Object.create(); +Object.defineProperties(); +Object.defineProperty(); +Object.entries(); +Object.freeze(); +Object.fromEntries(); +Object.getOwnPropertyDescriptor(); +Object.getOwnPropertyDescriptors(); +Object.getOwnPropertyNames(); +Object.getOwnPropertySymbols(); +Object.getPrototypeOf(); +Object.is(); +Object.isExtensible(); +Object.isFrozen(); +Object.isSealed(); +Object.keys(); +Object.preventExtensions(); +Object.seal(); +Object.setPrototypeOf(); +Object.values(); From 26a6dfa8e73d60b1432341ccf89eb2342266fa70 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Sun, 22 Jan 2023 11:26:12 +0800 Subject: [PATCH 13/14] methods of `console` shouldn't be considered as pure --- .../src/metadata/pure_exprs.rs | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs b/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs index 50c4852737c0..5eab42d53530 100644 --- a/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs +++ b/crates/swc_ecma_minifier/src/metadata/pure_exprs.rs @@ -205,27 +205,6 @@ fn preset_of_pure_func() -> Vec> { dummy_ident_expr!(setInterval), dummy_ident_expr!(setTimeout), dummy_ident_expr!(unescape), - // Console method references are assumed to have no side effects - // https://developer.mozilla.org/en-US/docs/Web/API/console - member_expr!(DUMMY_SP, console.assert), - member_expr!(DUMMY_SP, console.clear), - member_expr!(DUMMY_SP, console.count), - member_expr!(DUMMY_SP, console.countReset), - member_expr!(DUMMY_SP, console.debug), - member_expr!(DUMMY_SP, console.dir), - member_expr!(DUMMY_SP, console.dirxml), - member_expr!(DUMMY_SP, console.error), - member_expr!(DUMMY_SP, console.group), - member_expr!(DUMMY_SP, console.groupCollapsed), - member_expr!(DUMMY_SP, console.groupEnd), - member_expr!(DUMMY_SP, console.info), - member_expr!(DUMMY_SP, console.log), - member_expr!(DUMMY_SP, console.table), - member_expr!(DUMMY_SP, console.time), - member_expr!(DUMMY_SP, console.timeEnd), - member_expr!(DUMMY_SP, console.timeLog), - member_expr!(DUMMY_SP, console.trace), - member_expr!(DUMMY_SP, console.warn), // CSSOM APIs dummy_ident_expr!(CSSAnimation), dummy_ident_expr!(CSSFontFaceRule), From a7725c5a7b0439240464cee89facd5140ad0aaa5 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Tue, 24 Jan 2023 14:31:53 +0800 Subject: [PATCH 14/14] Format --- crates/swc_ecma_minifier/src/metadata/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 24f1ff392b71..a83b98c37c15 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -57,7 +57,6 @@ pub(crate) fn info_marker<'a>( marks: Marks, // unresolved_mark: Mark, ) -> impl 'a + VisitMut { - let pristine_globals = options.map_or(false, |opts| opts.pristine_globals); let mut pure_funcs = options .map(|opts| {