use rustc_hash::FxHashMap;
use swc_atoms::Atom;
use swc_common::{SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_utils::private_ident;
const fn min_usages_for_name(name_len: usize) -> usize {
if name_len <= 1 {
return usize::MAX; }
(name_len + 7 + (name_len - 2)) / (name_len - 1)
}
const MIN_USAGES_OBJECT_ASSIGN: usize = min_usages_for_name(13); const MIN_USAGES_OBJECT_KEYS: usize = min_usages_for_name(11); const MIN_USAGES_OBJECT_VALUES: usize = min_usages_for_name(13); const MIN_USAGES_OBJECT_ENTRIES: usize = min_usages_for_name(14); const MIN_USAGES_OBJECT_FROM_ENTRIES: usize = min_usages_for_name(18); const MIN_USAGES_OBJECT_FREEZE: usize = min_usages_for_name(13); const MIN_USAGES_OBJECT_SEAL: usize = min_usages_for_name(11); const MIN_USAGES_OBJECT_PREVENT_EXTENSIONS: usize = min_usages_for_name(24); const MIN_USAGES_OBJECT_IS_FROZEN: usize = min_usages_for_name(15); const MIN_USAGES_OBJECT_IS_SEALED: usize = min_usages_for_name(15); const MIN_USAGES_OBJECT_IS_EXTENSIBLE: usize = min_usages_for_name(19); const MIN_USAGES_OBJECT_GET_OWN_PROP_DESC: usize = min_usages_for_name(31); const MIN_USAGES_OBJECT_GET_OWN_PROP_DESCS: usize = min_usages_for_name(32); const MIN_USAGES_OBJECT_GET_OWN_PROP_NAMES: usize = min_usages_for_name(27); const MIN_USAGES_OBJECT_GET_OWN_PROP_SYMBOLS: usize = min_usages_for_name(29); const MIN_USAGES_OBJECT_GET_PROTOTYPE_OF: usize = min_usages_for_name(21); const MIN_USAGES_OBJECT_SET_PROTOTYPE_OF: usize = min_usages_for_name(21); const MIN_USAGES_OBJECT_CREATE: usize = min_usages_for_name(13); const MIN_USAGES_OBJECT_DEFINE_PROPERTY: usize = min_usages_for_name(21); const MIN_USAGES_OBJECT_DEFINE_PROPERTIES: usize = min_usages_for_name(23); const MIN_USAGES_OBJECT_HAS_OWN: usize = min_usages_for_name(13); const MIN_USAGES_OBJECT_IS: usize = min_usages_for_name(9);
const MIN_USAGES_ARRAY_IS_ARRAY: usize = min_usages_for_name(13); const MIN_USAGES_ARRAY_FROM: usize = min_usages_for_name(10); const MIN_USAGES_ARRAY_OF: usize = min_usages_for_name(8);
const MIN_USAGES_REFLECT_APPLY: usize = min_usages_for_name(13); const MIN_USAGES_REFLECT_CONSTRUCT: usize = min_usages_for_name(17); const MIN_USAGES_REFLECT_DEFINE_PROPERTY: usize = min_usages_for_name(22); const MIN_USAGES_REFLECT_DELETE_PROPERTY: usize = min_usages_for_name(22); const MIN_USAGES_REFLECT_GET: usize = min_usages_for_name(11); const MIN_USAGES_REFLECT_GET_OWN_PROP_DESC: usize = min_usages_for_name(32); const MIN_USAGES_REFLECT_GET_PROTOTYPE_OF: usize = min_usages_for_name(22); const MIN_USAGES_REFLECT_HAS: usize = min_usages_for_name(11); const MIN_USAGES_REFLECT_IS_EXTENSIBLE: usize = min_usages_for_name(20); const MIN_USAGES_REFLECT_OWN_KEYS: usize = min_usages_for_name(15); const MIN_USAGES_REFLECT_PREVENT_EXTENSIONS: usize = min_usages_for_name(25); const MIN_USAGES_REFLECT_SET: usize = min_usages_for_name(11); const MIN_USAGES_REFLECT_SET_PROTOTYPE_OF: usize = min_usages_for_name(22);
const MIN_USAGES_MATH_ABS: usize = min_usages_for_name(8); const MIN_USAGES_MATH_ACOS: usize = min_usages_for_name(9); const MIN_USAGES_MATH_ACOSH: usize = min_usages_for_name(10); const MIN_USAGES_MATH_ASIN: usize = min_usages_for_name(9); const MIN_USAGES_MATH_ASINH: usize = min_usages_for_name(10); const MIN_USAGES_MATH_ATAN: usize = min_usages_for_name(9); const MIN_USAGES_MATH_ATAN2: usize = min_usages_for_name(10); const MIN_USAGES_MATH_ATANH: usize = min_usages_for_name(10); const MIN_USAGES_MATH_CBRT: usize = min_usages_for_name(9); const MIN_USAGES_MATH_CEIL: usize = min_usages_for_name(9); const MIN_USAGES_MATH_CLZ32: usize = min_usages_for_name(10); const MIN_USAGES_MATH_COS: usize = min_usages_for_name(8); const MIN_USAGES_MATH_COSH: usize = min_usages_for_name(9); const MIN_USAGES_MATH_EXP: usize = min_usages_for_name(8); const MIN_USAGES_MATH_EXPM1: usize = min_usages_for_name(10); const MIN_USAGES_MATH_FLOOR: usize = min_usages_for_name(10); const MIN_USAGES_MATH_FROUND: usize = min_usages_for_name(11); const MIN_USAGES_MATH_HYPOT: usize = min_usages_for_name(10); const MIN_USAGES_MATH_IMUL: usize = min_usages_for_name(9); const MIN_USAGES_MATH_LOG: usize = min_usages_for_name(8); const MIN_USAGES_MATH_LOG10: usize = min_usages_for_name(10); const MIN_USAGES_MATH_LOG1P: usize = min_usages_for_name(10); const MIN_USAGES_MATH_LOG2: usize = min_usages_for_name(9); const MIN_USAGES_MATH_MAX: usize = min_usages_for_name(8); const MIN_USAGES_MATH_MIN: usize = min_usages_for_name(8); const MIN_USAGES_MATH_POW: usize = min_usages_for_name(8); const MIN_USAGES_MATH_RANDOM: usize = min_usages_for_name(11); const MIN_USAGES_MATH_ROUND: usize = min_usages_for_name(10); const MIN_USAGES_MATH_SIGN: usize = min_usages_for_name(9); const MIN_USAGES_MATH_SIN: usize = min_usages_for_name(8); const MIN_USAGES_MATH_SINH: usize = min_usages_for_name(9); const MIN_USAGES_MATH_SQRT: usize = min_usages_for_name(9); const MIN_USAGES_MATH_TAN: usize = min_usages_for_name(8); const MIN_USAGES_MATH_TANH: usize = min_usages_for_name(9); const MIN_USAGES_MATH_TRUNC: usize = min_usages_for_name(10);
const MIN_USAGES_STRING_FROM_CHAR_CODE: usize = min_usages_for_name(19); const MIN_USAGES_STRING_FROM_CODE_POINT: usize = min_usages_for_name(20); const MIN_USAGES_STRING_RAW: usize = min_usages_for_name(10);
const MIN_USAGES_NUMBER_IS_FINITE: usize = min_usages_for_name(15); const MIN_USAGES_NUMBER_IS_INTEGER: usize = min_usages_for_name(16); const MIN_USAGES_NUMBER_IS_NAN: usize = min_usages_for_name(12); const MIN_USAGES_NUMBER_IS_SAFE_INTEGER: usize = min_usages_for_name(20); const MIN_USAGES_NUMBER_PARSE_FLOAT: usize = min_usages_for_name(17); const MIN_USAGES_NUMBER_PARSE_INT: usize = min_usages_for_name(15);
const MIN_USAGES_JSON_PARSE: usize = min_usages_for_name(10); const MIN_USAGES_JSON_STRINGIFY: usize = min_usages_for_name(14);
const MIN_USAGES_PROMISE_ALL: usize = min_usages_for_name(11); const MIN_USAGES_PROMISE_ALL_SETTLED: usize = min_usages_for_name(18); const MIN_USAGES_PROMISE_ANY: usize = min_usages_for_name(11); const MIN_USAGES_PROMISE_RACE: usize = min_usages_for_name(12); const MIN_USAGES_PROMISE_REJECT: usize = min_usages_for_name(14); const MIN_USAGES_PROMISE_RESOLVE: usize = min_usages_for_name(15); const MIN_USAGES_PROMISE_WITH_RESOLVERS: usize = min_usages_for_name(21);
const MIN_USAGES_SYMBOL_FOR: usize = min_usages_for_name(10); const MIN_USAGES_SYMBOL_KEY_FOR: usize = min_usages_for_name(13);
const MIN_USAGES_MAP: usize = min_usages_for_name(3); const MIN_USAGES_SET: usize = min_usages_for_name(3); const MIN_USAGES_WEAK_MAP: usize = min_usages_for_name(7); const MIN_USAGES_WEAK_SET: usize = min_usages_for_name(7); const MIN_USAGES_PROMISE: usize = min_usages_for_name(7); const MIN_USAGES_PROXY: usize = min_usages_for_name(5); const MIN_USAGES_DATE: usize = min_usages_for_name(4); const MIN_USAGES_REGEXP: usize = min_usages_for_name(6); const MIN_USAGES_ERROR: usize = min_usages_for_name(5); const MIN_USAGES_TYPE_ERROR: usize = min_usages_for_name(9); const MIN_USAGES_RANGE_ERROR: usize = min_usages_for_name(10); const MIN_USAGES_SYNTAX_ERROR: usize = min_usages_for_name(11); const MIN_USAGES_REFERENCE_ERROR: usize = min_usages_for_name(14); const MIN_USAGES_URI_ERROR: usize = min_usages_for_name(8); const MIN_USAGES_EVAL_ERROR: usize = min_usages_for_name(9); const MIN_USAGES_ARRAY_BUFFER: usize = min_usages_for_name(11); const MIN_USAGES_SHARED_ARRAY_BUFFER: usize = min_usages_for_name(17); const MIN_USAGES_DATA_VIEW: usize = min_usages_for_name(8); const MIN_USAGES_INT8_ARRAY: usize = min_usages_for_name(9); const MIN_USAGES_UINT8_ARRAY: usize = min_usages_for_name(10); const MIN_USAGES_UINT8_CLAMPED_ARRAY: usize = min_usages_for_name(17); const MIN_USAGES_INT16_ARRAY: usize = min_usages_for_name(10); const MIN_USAGES_UINT16_ARRAY: usize = min_usages_for_name(11); const MIN_USAGES_INT32_ARRAY: usize = min_usages_for_name(10); const MIN_USAGES_UINT32_ARRAY: usize = min_usages_for_name(11); const MIN_USAGES_FLOAT32_ARRAY: usize = min_usages_for_name(12); const MIN_USAGES_FLOAT64_ARRAY: usize = min_usages_for_name(12); const MIN_USAGES_BIG_INT64_ARRAY: usize = min_usages_for_name(13); const MIN_USAGES_BIG_UINT64_ARRAY: usize = min_usages_for_name(14); const MIN_USAGES_URL: usize = min_usages_for_name(3); const MIN_USAGES_URL_SEARCH_PARAMS: usize = min_usages_for_name(15); const MIN_USAGES_TEXT_ENCODER: usize = min_usages_for_name(11); const MIN_USAGES_TEXT_DECODER: usize = min_usages_for_name(11);
fn get_static_method_min_usages(obj: &str, prop: &str) -> Option<usize> {
match obj {
"Object" => match prop {
"assign" => Some(MIN_USAGES_OBJECT_ASSIGN),
"keys" => Some(MIN_USAGES_OBJECT_KEYS),
"values" => Some(MIN_USAGES_OBJECT_VALUES),
"entries" => Some(MIN_USAGES_OBJECT_ENTRIES),
"fromEntries" => Some(MIN_USAGES_OBJECT_FROM_ENTRIES),
"freeze" => Some(MIN_USAGES_OBJECT_FREEZE),
"seal" => Some(MIN_USAGES_OBJECT_SEAL),
"preventExtensions" => Some(MIN_USAGES_OBJECT_PREVENT_EXTENSIONS),
"isFrozen" => Some(MIN_USAGES_OBJECT_IS_FROZEN),
"isSealed" => Some(MIN_USAGES_OBJECT_IS_SEALED),
"isExtensible" => Some(MIN_USAGES_OBJECT_IS_EXTENSIBLE),
"getOwnPropertyDescriptor" => Some(MIN_USAGES_OBJECT_GET_OWN_PROP_DESC),
"getOwnPropertyDescriptors" => Some(MIN_USAGES_OBJECT_GET_OWN_PROP_DESCS),
"getOwnPropertyNames" => Some(MIN_USAGES_OBJECT_GET_OWN_PROP_NAMES),
"getOwnPropertySymbols" => Some(MIN_USAGES_OBJECT_GET_OWN_PROP_SYMBOLS),
"getPrototypeOf" => Some(MIN_USAGES_OBJECT_GET_PROTOTYPE_OF),
"setPrototypeOf" => Some(MIN_USAGES_OBJECT_SET_PROTOTYPE_OF),
"create" => Some(MIN_USAGES_OBJECT_CREATE),
"defineProperty" => Some(MIN_USAGES_OBJECT_DEFINE_PROPERTY),
"defineProperties" => Some(MIN_USAGES_OBJECT_DEFINE_PROPERTIES),
"hasOwn" => Some(MIN_USAGES_OBJECT_HAS_OWN),
"is" => Some(MIN_USAGES_OBJECT_IS),
_ => None,
},
"Array" => match prop {
"isArray" => Some(MIN_USAGES_ARRAY_IS_ARRAY),
"from" => Some(MIN_USAGES_ARRAY_FROM),
"of" => Some(MIN_USAGES_ARRAY_OF),
_ => None,
},
"Reflect" => match prop {
"apply" => Some(MIN_USAGES_REFLECT_APPLY),
"construct" => Some(MIN_USAGES_REFLECT_CONSTRUCT),
"defineProperty" => Some(MIN_USAGES_REFLECT_DEFINE_PROPERTY),
"deleteProperty" => Some(MIN_USAGES_REFLECT_DELETE_PROPERTY),
"get" => Some(MIN_USAGES_REFLECT_GET),
"getOwnPropertyDescriptor" => Some(MIN_USAGES_REFLECT_GET_OWN_PROP_DESC),
"getPrototypeOf" => Some(MIN_USAGES_REFLECT_GET_PROTOTYPE_OF),
"has" => Some(MIN_USAGES_REFLECT_HAS),
"isExtensible" => Some(MIN_USAGES_REFLECT_IS_EXTENSIBLE),
"ownKeys" => Some(MIN_USAGES_REFLECT_OWN_KEYS),
"preventExtensions" => Some(MIN_USAGES_REFLECT_PREVENT_EXTENSIONS),
"set" => Some(MIN_USAGES_REFLECT_SET),
"setPrototypeOf" => Some(MIN_USAGES_REFLECT_SET_PROTOTYPE_OF),
_ => None,
},
"Math" => match prop {
"abs" => Some(MIN_USAGES_MATH_ABS),
"acos" => Some(MIN_USAGES_MATH_ACOS),
"acosh" => Some(MIN_USAGES_MATH_ACOSH),
"asin" => Some(MIN_USAGES_MATH_ASIN),
"asinh" => Some(MIN_USAGES_MATH_ASINH),
"atan" => Some(MIN_USAGES_MATH_ATAN),
"atan2" => Some(MIN_USAGES_MATH_ATAN2),
"atanh" => Some(MIN_USAGES_MATH_ATANH),
"cbrt" => Some(MIN_USAGES_MATH_CBRT),
"ceil" => Some(MIN_USAGES_MATH_CEIL),
"clz32" => Some(MIN_USAGES_MATH_CLZ32),
"cos" => Some(MIN_USAGES_MATH_COS),
"cosh" => Some(MIN_USAGES_MATH_COSH),
"exp" => Some(MIN_USAGES_MATH_EXP),
"expm1" => Some(MIN_USAGES_MATH_EXPM1),
"floor" => Some(MIN_USAGES_MATH_FLOOR),
"fround" => Some(MIN_USAGES_MATH_FROUND),
"hypot" => Some(MIN_USAGES_MATH_HYPOT),
"imul" => Some(MIN_USAGES_MATH_IMUL),
"log" => Some(MIN_USAGES_MATH_LOG),
"log10" => Some(MIN_USAGES_MATH_LOG10),
"log1p" => Some(MIN_USAGES_MATH_LOG1P),
"log2" => Some(MIN_USAGES_MATH_LOG2),
"max" => Some(MIN_USAGES_MATH_MAX),
"min" => Some(MIN_USAGES_MATH_MIN),
"pow" => Some(MIN_USAGES_MATH_POW),
"random" => Some(MIN_USAGES_MATH_RANDOM),
"round" => Some(MIN_USAGES_MATH_ROUND),
"sign" => Some(MIN_USAGES_MATH_SIGN),
"sin" => Some(MIN_USAGES_MATH_SIN),
"sinh" => Some(MIN_USAGES_MATH_SINH),
"sqrt" => Some(MIN_USAGES_MATH_SQRT),
"tan" => Some(MIN_USAGES_MATH_TAN),
"tanh" => Some(MIN_USAGES_MATH_TANH),
"trunc" => Some(MIN_USAGES_MATH_TRUNC),
_ => None,
},
"String" => match prop {
"fromCharCode" => Some(MIN_USAGES_STRING_FROM_CHAR_CODE),
"fromCodePoint" => Some(MIN_USAGES_STRING_FROM_CODE_POINT),
"raw" => Some(MIN_USAGES_STRING_RAW),
_ => None,
},
"Number" => match prop {
"isFinite" => Some(MIN_USAGES_NUMBER_IS_FINITE),
"isInteger" => Some(MIN_USAGES_NUMBER_IS_INTEGER),
"isNaN" => Some(MIN_USAGES_NUMBER_IS_NAN),
"isSafeInteger" => Some(MIN_USAGES_NUMBER_IS_SAFE_INTEGER),
"parseFloat" => Some(MIN_USAGES_NUMBER_PARSE_FLOAT),
"parseInt" => Some(MIN_USAGES_NUMBER_PARSE_INT),
_ => None,
},
"JSON" => match prop {
"parse" => Some(MIN_USAGES_JSON_PARSE),
"stringify" => Some(MIN_USAGES_JSON_STRINGIFY),
_ => None,
},
"Promise" => match prop {
"all" => Some(MIN_USAGES_PROMISE_ALL),
"allSettled" => Some(MIN_USAGES_PROMISE_ALL_SETTLED),
"any" => Some(MIN_USAGES_PROMISE_ANY),
"race" => Some(MIN_USAGES_PROMISE_RACE),
"reject" => Some(MIN_USAGES_PROMISE_REJECT),
"resolve" => Some(MIN_USAGES_PROMISE_RESOLVE),
"withResolvers" => Some(MIN_USAGES_PROMISE_WITH_RESOLVERS),
_ => None,
},
"Symbol" => match prop {
"for" => Some(MIN_USAGES_SYMBOL_FOR),
"keyFor" => Some(MIN_USAGES_SYMBOL_KEY_FOR),
_ => None,
},
_ => None,
}
}
fn get_global_object_min_usages(name: &str) -> Option<usize> {
match name {
"Map" => Some(MIN_USAGES_MAP),
"Set" => Some(MIN_USAGES_SET),
"WeakMap" => Some(MIN_USAGES_WEAK_MAP),
"WeakSet" => Some(MIN_USAGES_WEAK_SET),
"Promise" => Some(MIN_USAGES_PROMISE),
"Proxy" => Some(MIN_USAGES_PROXY),
"Date" => Some(MIN_USAGES_DATE),
"RegExp" => Some(MIN_USAGES_REGEXP),
"Error" => Some(MIN_USAGES_ERROR),
"TypeError" => Some(MIN_USAGES_TYPE_ERROR),
"RangeError" => Some(MIN_USAGES_RANGE_ERROR),
"SyntaxError" => Some(MIN_USAGES_SYNTAX_ERROR),
"ReferenceError" => Some(MIN_USAGES_REFERENCE_ERROR),
"URIError" => Some(MIN_USAGES_URI_ERROR),
"EvalError" => Some(MIN_USAGES_EVAL_ERROR),
"ArrayBuffer" => Some(MIN_USAGES_ARRAY_BUFFER),
"SharedArrayBuffer" => Some(MIN_USAGES_SHARED_ARRAY_BUFFER),
"DataView" => Some(MIN_USAGES_DATA_VIEW),
"Int8Array" => Some(MIN_USAGES_INT8_ARRAY),
"Uint8Array" => Some(MIN_USAGES_UINT8_ARRAY),
"Uint8ClampedArray" => Some(MIN_USAGES_UINT8_CLAMPED_ARRAY),
"Int16Array" => Some(MIN_USAGES_INT16_ARRAY),
"Uint16Array" => Some(MIN_USAGES_UINT16_ARRAY),
"Int32Array" => Some(MIN_USAGES_INT32_ARRAY),
"Uint32Array" => Some(MIN_USAGES_UINT32_ARRAY),
"Float32Array" => Some(MIN_USAGES_FLOAT32_ARRAY),
"Float64Array" => Some(MIN_USAGES_FLOAT64_ARRAY),
"BigInt64Array" => Some(MIN_USAGES_BIG_INT64_ARRAY),
"BigUint64Array" => Some(MIN_USAGES_BIG_UINT64_ARRAY),
"URL" => Some(MIN_USAGES_URL),
"URLSearchParams" => Some(MIN_USAGES_URL_SEARCH_PARAMS),
"TextEncoder" => Some(MIN_USAGES_TEXT_ENCODER),
"TextDecoder" => Some(MIN_USAGES_TEXT_DECODER),
_ => None,
}
}
pub type StaticMethodKey = (Atom, Atom);
#[derive(Default)]
pub struct StaticAliasState {
pub static_method_counts: FxHashMap<StaticMethodKey, usize>,
pub global_object_counts: FxHashMap<Atom, usize>,
pub static_method_aliases: FxHashMap<StaticMethodKey, Ident>,
pub global_object_aliases: FxHashMap<Atom, Ident>,
pub var_decls: Vec<VarDeclarator>,
pub aliases_built: bool,
pub var_decls_inserted: bool,
pub replacements_made: bool,
}
impl StaticAliasState {
pub fn try_record_static_method_call(
&mut self,
callee: &Expr,
unresolved_ctxt: SyntaxContext,
enabled: bool,
) {
if !enabled || self.aliases_built {
return;
}
if let Some((obj, prop)) = extract_static_method(callee, unresolved_ctxt) {
if get_static_method_min_usages(&obj, &prop).is_some() {
*self.static_method_counts.entry((obj, prop)).or_insert(0) += 1;
}
}
}
pub fn try_record_global_object(
&mut self,
callee: &Expr,
unresolved_ctxt: SyntaxContext,
enabled: bool,
) {
if !enabled || self.aliases_built {
return;
}
if let Some(ident) = callee.as_ident() {
if ident.ctxt == unresolved_ctxt && get_global_object_min_usages(&ident.sym).is_some() {
*self
.global_object_counts
.entry(ident.sym.clone())
.or_insert(0) += 1;
}
}
}
pub fn try_replace_static_method_call(
&mut self,
callee: &mut Box<Expr>,
unresolved_ctxt: SyntaxContext,
) -> bool {
if !self.aliases_built {
return false;
}
if let Some((obj, prop)) = extract_static_method(callee, unresolved_ctxt) {
if let Some(alias) = self.static_method_aliases.get(&(obj, prop)) {
*callee = Box::new(alias.clone().into());
self.replacements_made = true;
return true;
}
}
false
}
pub fn try_replace_global_object(
&mut self,
callee: &mut Box<Expr>,
unresolved_ctxt: SyntaxContext,
) -> bool {
if !self.aliases_built {
return false;
}
if let Some(ident) = callee.as_ident() {
if ident.ctxt == unresolved_ctxt {
if let Some(alias) = self.global_object_aliases.get(&ident.sym) {
*callee = Box::new(alias.clone().into());
self.replacements_made = true;
return true;
}
}
}
false
}
pub fn build_aliases_from_counts(&mut self, unresolved_ctxt: SyntaxContext) -> bool {
if self.aliases_built {
return false;
}
self.aliases_built = true;
let mut static_method_keys: Vec<_> = self.static_method_counts.drain().collect();
static_method_keys.sort_by(|a, b| a.0.cmp(&b.0));
for ((obj, prop), count) in static_method_keys {
if let Some(min_usages) = get_static_method_min_usages(&obj, &prop) {
if count >= min_usages {
let alias_ident = private_ident!(format!("_{}_{}", obj, prop));
let init = MemberExpr {
span: DUMMY_SP,
obj: Box::new(Ident::new(obj.clone(), DUMMY_SP, unresolved_ctxt).into()),
prop: MemberProp::Ident(IdentName::new(prop.clone(), DUMMY_SP)),
};
self.var_decls.push(VarDeclarator {
span: DUMMY_SP,
name: alias_ident.clone().into(),
init: Some(Box::new(init.into())),
definite: false,
});
self.static_method_aliases.insert((obj, prop), alias_ident);
}
}
}
let mut global_object_keys: Vec<_> = self.global_object_counts.drain().collect();
global_object_keys.sort_by(|a, b| a.0.cmp(&b.0));
for (name, count) in global_object_keys {
if let Some(min_usages) = get_global_object_min_usages(&name) {
if count >= min_usages {
let alias_ident = private_ident!(format!("_{}", name));
let init = Ident::new(name.clone(), DUMMY_SP, unresolved_ctxt);
self.var_decls.push(VarDeclarator {
span: DUMMY_SP,
name: alias_ident.clone().into(),
init: Some(Box::new(init.into())),
definite: false,
});
self.global_object_aliases.insert(name, alias_ident);
}
}
}
!self.static_method_aliases.is_empty() || !self.global_object_aliases.is_empty()
}
pub fn should_insert_var_decls(&self) -> bool {
self.aliases_built
&& self.replacements_made
&& !self.var_decls_inserted
&& !self.var_decls.is_empty()
}
pub fn take_var_decls(&mut self) -> Vec<VarDeclarator> {
self.var_decls_inserted = true;
std::mem::take(&mut self.var_decls)
}
}
fn extract_static_method(expr: &Expr, unresolved_ctxt: SyntaxContext) -> Option<(Atom, Atom)> {
let member = expr.as_member()?;
let obj = member.obj.as_ident()?;
if obj.ctxt != unresolved_ctxt {
return None;
}
if member.prop.is_computed() {
return None;
}
let prop = member.prop.as_ident()?;
Some((obj.sym.clone(), prop.sym.clone()))
}