diff --git a/packages/transformers/js/core/src/global_replacer.rs b/packages/transformers/js/core/src/global_replacer.rs index 3237b0f7e0d..d91aca37af9 100644 --- a/packages/transformers/js/core/src/global_replacer.rs +++ b/packages/transformers/js/core/src/global_replacer.rs @@ -18,7 +18,6 @@ pub struct GlobalReplacer<'a> { pub project_root: &'a Path, pub filename: &'a Path, pub decls: &'a mut HashSet<(JsWord, SyntaxContext)>, - pub global_mark: swc_common::Mark, pub scope_hoist: bool, } @@ -150,15 +149,8 @@ impl<'a> Fold for GlobalReplacer<'a> { } } -fn create_decl_stmt( - name: swc_atoms::JsWord, - global_mark: swc_common::Mark, - init: ast::Expr, -) -> (ast::Stmt, SyntaxContext) { - let span = DUMMY_SP - // TODO this shouldn't actually be marked global because it's generated - .apply_mark(global_mark) - .apply_mark(Mark::fresh(Mark::root())); +fn create_decl_stmt(name: swc_atoms::JsWord, init: ast::Expr) -> (ast::Stmt, SyntaxContext) { + let span = DUMMY_SP.apply_mark(Mark::fresh(Mark::root())); ( ast::Stmt::Decl(ast::Decl::Var(ast::VarDecl { @@ -185,7 +177,7 @@ impl GlobalReplacer<'_> { id.span.ctxt = *ctxt; false } else { - let (decl, ctxt) = create_decl_stmt(id.sym.clone(), self.global_mark, expr(self)); + let (decl, ctxt) = create_decl_stmt(id.sym.clone(), expr(self)); id.span.ctxt = ctxt; diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index 6f9b4a1b604..1a9f9783f6a 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -785,10 +785,6 @@ impl<'a> Fold for Hoist<'a> { return Ident::new("$parcel$global".into(), node.span); } - // TODO - // neither ctxt == DUMMY_SP.apply_mark(global_mark) - // nor span.has_mark(self.collect.global_mark) - // are correct. if node.span.has_mark(self.collect.global_mark) && self.collect.decls.contains(&id!(node)) && !self.collect.should_wrap @@ -1078,7 +1074,6 @@ pub struct Collect { pub decls: HashSet, pub ignore_mark: Mark, pub global_mark: Mark, - pub global_ctxt: SyntaxContext, pub static_cjs_exports: bool, pub has_cjs_exports: bool, pub is_esm: bool, @@ -1145,7 +1140,6 @@ impl Collect { decls, ignore_mark, global_mark, - global_ctxt: SyntaxContext::empty().apply_mark(global_mark), static_cjs_exports: true, has_cjs_exports: false, is_esm: false, @@ -1554,11 +1548,7 @@ impl Visit for Collect { .or_insert_with(|| node.id.sym.clone()); } - // TODO - // neither ctxt == DUMMY_SP.apply_mark(global_mark) - // nor span.has_mark(self.collect.global_mark) - // are correct. - if self.in_assign && node.id.span.ctxt() == self.global_ctxt { + if self.in_assign && node.id.span.has_mark(self.global_mark) { self .non_const_bindings .entry(id!(node.id)) @@ -1583,11 +1573,7 @@ impl Visit for Collect { .or_insert_with(|| node.key.sym.clone()); } - // TODO - // neither ctxt == DUMMY_SP.apply_mark(global_mark) - // nor span.has_mark(self.collect.global_mark) - // are correct. - if self.in_assign && node.key.span.ctxt() == self.global_ctxt { + if self.in_assign && node.key.span.has_mark(self.global_mark) { self .non_const_bindings .entry(id!(node.key)) diff --git a/packages/transformers/js/core/src/lib.rs b/packages/transformers/js/core/src/lib.rs index 106154aa1f6..fd03b1c6603 100644 --- a/packages/transformers/js/core/src/lib.rs +++ b/packages/transformers/js/core/src/lib.rs @@ -345,7 +345,6 @@ pub fn transform(config: Config) -> Result { project_root: Path::new(&config.project_root), filename: Path::new(&config.filename), decls: &mut decls, - global_mark, scope_hoist: config.scope_hoist }, config.insert_node_globals && config.source_type != SourceType::Script @@ -370,6 +369,9 @@ pub fn transform(config: Config) -> Result { module.fold_with(&mut passes) }; + // regnerate decls after preset-env ran + let mut decls = collect_decls(&module); + let mut has_node_replacements = false; let module = module.fold_with( // Replace __dirname and __filename with placeholders in Node env @@ -381,7 +383,6 @@ pub fn transform(config: Config) -> Result { project_root: Path::new(&config.project_root), filename: Path::new(&config.filename), decls: &mut decls, - global_mark, scope_hoist: config.scope_hoist, has_node_replacements: &mut has_node_replacements, }, @@ -412,6 +413,19 @@ pub fn transform(config: Config) -> Result { return Ok(result); } + // Flush (JsWord, SyntaxContexts) into unique names and reresolve to + // set global_mark for all nodes, even generated ones. + // (This changes the syntax context ids and therefore invalidates decls) + let (decls, module) = if config.scope_hoist { + let module = module.fold_with(&mut chain!( + hygiene(), + resolver(unresolved_mark, global_mark, false) + )); + (collect_decls(&module), module) + } else { + (decls, module) + }; + let mut collect = Collect::new( source_map.clone(), decls, diff --git a/packages/transformers/js/core/src/node_replacer.rs b/packages/transformers/js/core/src/node_replacer.rs index 7a7db70d634..ac439e5eb85 100644 --- a/packages/transformers/js/core/src/node_replacer.rs +++ b/packages/transformers/js/core/src/node_replacer.rs @@ -18,7 +18,6 @@ pub struct NodeReplacer<'a> { pub project_root: &'a Path, pub filename: &'a Path, pub decls: &'a mut HashSet<(JsWord, SyntaxContext)>, - pub global_mark: swc_common::Mark, pub scope_hoist: bool, pub has_node_replacements: &'a mut bool, } @@ -184,15 +183,8 @@ impl<'a> Fold for NodeReplacer<'a> { } } -fn create_decl_stmt( - name: swc_atoms::JsWord, - global_mark: swc_common::Mark, - init: ast::Expr, -) -> (ast::Stmt, SyntaxContext) { - let span = DUMMY_SP - // TODO this shouldn't actually be marked global because it's generated - .apply_mark(global_mark) - .apply_mark(Mark::fresh(Mark::root())); +fn create_decl_stmt(name: swc_atoms::JsWord, init: ast::Expr) -> (ast::Stmt, SyntaxContext) { + let span = DUMMY_SP.apply_mark(Mark::fresh(Mark::root())); ( ast::Stmt::Decl(ast::Decl::Var(ast::VarDecl { @@ -219,7 +211,7 @@ impl NodeReplacer<'_> { id.span.ctxt = *ctxt; false } else { - let (decl, ctxt) = create_decl_stmt(id.sym.clone(), self.global_mark, expr(self)); + let (decl, ctxt) = create_decl_stmt(id.sym.clone(), expr(self)); id.span.ctxt = ctxt;