diff --git a/bundler/Cargo.toml b/bundler/Cargo.toml index 9ec9b78186e1..57903b754bf9 100644 --- a/bundler/Cargo.toml +++ b/bundler/Cargo.toml @@ -5,10 +5,11 @@ build = "build.rs" description = "Very fast ecmascript bundler" documentation = "https://swc.rs/rustdoc/swc_bundler/" edition = "2018" +include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0/MIT" name = "swc_bundler" repository = "https://github.com/swc-project/swc.git" -version = "0.19.1" +version = "0.19.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] @@ -33,7 +34,7 @@ swc_common = {version = "0.10.0", path = "../common"} swc_ecma_ast = {version = "0.36.0", path = "../ecmascript/ast"} swc_ecma_codegen = {version = "0.42.0", path = "../ecmascript/codegen"} swc_ecma_parser = {version = "0.44.0", path = "../ecmascript/parser"} -swc_ecma_transforms = {version = "0.32.0", path = "../ecmascript/transforms", features = ["optimization"]} +swc_ecma_transforms = {version = "0.32.1", path = "../ecmascript/transforms", features = ["optimization"]} swc_ecma_utils = {version = "0.26.0", path = "../ecmascript/utils"} swc_ecma_visit = {version = "0.22.0", path = "../ecmascript/visit"} diff --git a/bundler/src/bundler/chunk/circular.rs b/bundler/src/bundler/chunk/circular.rs index a42424c46976..a91efd6f8756 100644 --- a/bundler/src/bundler/chunk/circular.rs +++ b/bundler/src/bundler/chunk/circular.rs @@ -70,24 +70,6 @@ where } _ => {} }, - ModuleDecl::ExportNamed(export) => { - for specifier in &mut export.specifiers { - match specifier { - ExportSpecifier::Namespace(_) => {} - ExportSpecifier::Default(_) => {} - ExportSpecifier::Named(named) => { - let mut orig = named.orig.clone(); - orig.span.ctxt = entry_module.export_ctxt(); - - exports.push(ExportSpecifier::Named(ExportNamedSpecifier { - span: export.span, - orig, - exported: named.exported.clone(), - })); - } - } - } - } ModuleDecl::ExportDefaultDecl(_) => {} ModuleDecl::ExportDefaultExpr(_) => {} ModuleDecl::ExportAll(_) => {} @@ -99,7 +81,7 @@ where // print_hygiene("[circular] entry:init", &self.cm, &entry); - self.handle_import_deps(ctx, &entry_module, &mut entry, true); + // self.handle_import_deps(ctx, &entry_module, &mut entry, true); // print_hygiene("[circular] entry:reexport", &self.cm, &entry); @@ -167,7 +149,7 @@ where // print_hygiene("[circular] dep:init 2", &self.cm, &dep); - entry.prepend_all(dep); + entry.push_all(dep); } // print_hygiene("before circular sort", &self.cm, &entry.clone().into()); diff --git a/bundler/src/bundler/chunk/computed_key.rs b/bundler/src/bundler/chunk/computed_key.rs index 36a1d1833b21..05444fce2c53 100644 --- a/bundler/src/bundler/chunk/computed_key.rs +++ b/bundler/src/bundler/chunk/computed_key.rs @@ -1,4 +1,6 @@ use crate::bundler::modules::Modules; +use crate::util::ExprExt; +use crate::util::VarDeclaratorExt; use crate::{bundler::chunk::merge::Ctx, Bundler, Load, ModuleId, Resolve}; use anyhow::{bail, Error}; use std::mem::take; @@ -40,7 +42,40 @@ where Some(v) => v, None => bail!("{:?} should not be wrapped with a function", id), }; - module.sort(); + let injected_ctxt = self.injected_ctxt; + let mut injected_vars = vec![]; + module.iter_mut().for_each(|item| match item { + ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(export)) => { + // + for s in export.specifiers.iter_mut() { + match s { + ExportSpecifier::Named(ExportNamedSpecifier { + span, + exported: Some(exported), + orig, + .. + }) => { + // Allow using variables within the wrapped es module. + injected_vars.push( + orig.clone().assign_to(exported.clone()).into_module_item( + injected_ctxt, + "wrapped esm -> aliased export", + ), + ); + *s = ExportSpecifier::Named(ExportNamedSpecifier { + span: *span, + exported: None, + orig: exported.clone(), + }) + } + _ => {} + } + } + } + _ => {} + }); + module.inject_all(injected_vars); + module.sort(&self.cm); let is_async = { let mut v = TopLevelAwaitFinder { found: false }; diff --git a/bundler/src/bundler/chunk/export.rs b/bundler/src/bundler/chunk/export.rs index 434b153d60b3..1270a8dd7c19 100644 --- a/bundler/src/bundler/chunk/export.rs +++ b/bundler/src/bundler/chunk/export.rs @@ -1,21 +1,19 @@ use crate::bundler::modules::Modules; +use crate::util::MapWithMut; use crate::{ bundler::{ chunk::merge::Ctx, - load::{Source, Specifier, TransformedModule}, + load::{Source, Specifier}, }, - util::{ExprExt, MapWithMut, VarDeclaratorExt}, + util::{ExprExt, VarDeclaratorExt}, Bundler, Load, ModuleId, Resolve, }; use anyhow::{Context, Error}; #[cfg(feature = "concurrent")] use rayon::iter::ParallelIterator; -use retain_mut::RetainMut; -use std::mem::replace; -use swc_atoms::js_word; -use swc_common::{Spanned, SyntaxContext, DUMMY_SP}; +use swc_common::{SyntaxContext, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_utils::{find_ids, ident::IdentLike, Id}; +use swc_ecma_utils::{ident::IdentLike, Id}; use swc_ecma_visit::{noop_fold_type, Fold}; impl Bundler<'_, L, R> @@ -67,68 +65,6 @@ where .merge_modules(ctx, dep_id, false, true) .context("failed to get module for merging")?; - // print_hygiene( - // &format!( - // "reexport: load dep: {} ({:?}, {:?})", - // dep_info.fm.name, - // dep_info.local_ctxt(), - // dep_info.export_ctxt() - // ), - // &self.cm, - // &dep, - // ); - - self.handle_reexport(&dep_info, &mut dep); - - // print_hygiene( - // &format!("dep: handle reexport"), - // &self.cm, - // &dep.clone().into(), - // ); - - // for stmt in &mut dep.body { - // let decl = match stmt { - // ModuleItem::ModuleDecl(decl) => decl, - // ModuleItem::Stmt(_) => continue, - // }; - - // match decl { - // ModuleDecl::ExportDecl(_) => {} - // ModuleDecl::ExportNamed(export) => { - // for specifier in &mut export.specifiers { - // match specifier { - // ExportSpecifier::Namespace(ns) => {} - // ExportSpecifier::Default(default) => {} - // ExportSpecifier::Named(named) => match &mut - // named.exported { Some(exported) => { - // if exported.span.ctxt != dep_info.local_ctxt() { - // continue; - // } - - // exported.span = - // - // exported.span.with_ctxt(dep_info.export_ctxt()); - // } None => { - // if named.orig.span.ctxt != dep_info.local_ctxt() - // { continue; - // } - - // named.exported = Some(Ident::new( - // named.orig.sym.clone(), - // - // named.orig.span.with_ctxt(dep_info.export_ctxt()), - // )); } - // }, - // } - // } - // } - // ModuleDecl::ExportDefaultDecl(_) => {} - // ModuleDecl::ExportDefaultExpr(_) => {} - // ModuleDecl::ExportAll(_) => {} - // _ => {} - // } - // } - if let Some(module_name) = self.scope.wrapped_esm_id(dep_info.id) { dep = self.wrap_esm(ctx, dep_info.id, dep.into())?; @@ -147,6 +83,12 @@ where } } + // print_hygiene( + // &format!("dep: before unexport"), + // &self.cm, + // &dep.clone().into(), + // ); + if !specifiers.is_empty() { unexprt_as_var(&mut dep, dep_info.export_ctxt()); @@ -163,187 +105,6 @@ where Ok(dep) }) } - - /// # ExportDecl - /// - /// For exported declarations, We should inject named exports. - /// - /// ```ts - /// export const b__9 = 1; - /// console.log(b__9); - /// ``` - /// - /// ```ts - /// const b__9 = 1; - /// export { b__9 as b__10 }; - /// console.log(b__9); - /// ``` - fn handle_reexport(&self, info: &TransformedModule, module: &mut Modules) { - let mut vars = vec![]; - - module.map_any_items(|stmts| { - let mut new_body = Vec::with_capacity(stmts.len() + 32); - - for mut stmt in stmts { - match &mut stmt { - ModuleItem::ModuleDecl(ModuleDecl::Import(import)) => { - for specifier in &import.specifiers { - match specifier { - ImportSpecifier::Named(named) => match &named.imported { - Some(imported) => { - vars.push(imported.clone().assign_to(named.local.clone())); - } - None => {} - }, - ImportSpecifier::Default(default) => { - let imported = Ident::new( - js_word!("default"), - DUMMY_SP.with_ctxt(import.span.ctxt), - ); - vars.push(imported.clone().assign_to(default.local.clone())); - } - _ => {} - } - } - import.specifiers.clear(); - } - - ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(export)) => { - match &mut export.decl { - DefaultDecl::Class(expr) => { - let expr = expr.take(); - let export_name = Ident::new( - js_word!("default"), - export.span.with_ctxt(info.export_ctxt()), - ); - - let (init, s) = match expr.ident { - Some(name) => { - ( - Expr::Ident(name.clone()), - ModuleItem::Stmt(Stmt::Decl(Decl::Class(ClassDecl { - // Context of the span is local. - ident: name, - declare: false, - class: expr.class, - }))), - ) - } - None => ( - Expr::Class(expr), - ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP })), - ), - }; - - vars.push(VarDeclarator { - span: DUMMY_SP, - name: Pat::Ident(export_name.clone()), - init: Some(Box::new(init)), - definite: false, - }); - - let export_specifier = - ExportSpecifier::Named(ExportNamedSpecifier { - span: DUMMY_SP, - orig: export_name.clone(), - exported: Some(export_name.clone()), - }); - new_body.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( - NamedExport { - span: DUMMY_SP.with_ctxt(self.synthesized_ctxt), - specifiers: vec![export_specifier], - src: None, - type_only: false, - }, - ))); - - stmt = s; - } - DefaultDecl::Fn(expr) => { - let expr = expr.take(); - let export_name = Ident::new( - js_word!("default"), - export.span.with_ctxt(info.export_ctxt()), - ); - - let (init, s) = match expr.ident { - Some(name) => ( - Expr::Ident(name.clone()), - ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { - ident: name, - declare: false, - function: expr.function, - }))), - ), - None => ( - Expr::Fn(expr), - ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP })), - ), - }; - - vars.push(init.assign_to(export_name.clone())); - - let export_specifier = - ExportSpecifier::Named(ExportNamedSpecifier { - span: DUMMY_SP, - orig: export_name.clone(), - exported: Some(export_name.clone()), - }); - new_body.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( - NamedExport { - span: DUMMY_SP.with_ctxt(self.synthesized_ctxt), - specifiers: vec![export_specifier], - src: None, - type_only: false, - }, - ))); - - stmt = s; - } - DefaultDecl::TsInterfaceDecl(_) => {} - } - } - - ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(export)) => { - match &export.decl { - Decl::Class(ClassDecl { ident, .. }) - | Decl::Fn(FnDecl { ident, .. }) => { - let mut exported = ident.clone(); - exported.span.ctxt = info.export_ctxt(); - - vars.push(ident.clone().assign_to(exported)); - } - Decl::Var(var) => { - // - let ids: Vec = find_ids(&var.decls); - - vars.extend( - ids.into_iter() - .map(|i| { - let mut exported = i.clone(); - exported.span.ctxt = info.export_ctxt(); - - i.assign_to(exported) - }) - .map(From::from), - ); - } - _ => {} - }; - } - - _ => {} - } - - new_body.push(stmt); - } - - new_body - }); - for var in vars { - module.inject(var.into_module_item(self.injected_ctxt, "from_export_rs")) - } - } } pub(super) fn inject_export( @@ -353,195 +114,64 @@ pub(super) fn inject_export( wrapped: bool, dep: Modules, source: Source, -) -> Result<(), Modules> { - let injected_ctxt = entry.injected_ctxt; - let mut dep = Some(dep); - // This is required because `export *` does not exports `default` from the - // source. - // But as user may specify both of `export *` and `export { default }` from same - // module, we have to store it somewhere. - let mut export_default_stmt = None; - let mut vars = vec![]; - entry.map_any_items(|items| { - let mut buf = vec![]; - - for item in items { - // - match item { - ModuleItem::Stmt(Stmt::Empty(..)) => continue, - - // If the case of importing and exporting from same module, we firstly - // handle it using export.rs - // - // This works for the most time, but if the import has an alias, export - // handler cannot handle this. So we inject some variables to connnect them. - // - // See: https://github.com/swc-project/swc/issues/1150 - ModuleItem::ModuleDecl(ModuleDecl::Import(ref import)) - if import.src.value == source.src.value => - { - if let Some(dep) = dep.take() { - buf.extend(dep.into_items()); - } - - let decls = import - .specifiers - .iter() - .filter_map(|specifier| match specifier { - ImportSpecifier::Named(ImportNamedSpecifier { - local, - imported: Some(imported), - .. - }) => { - let mut imported = imported.clone(); - imported.span = imported.span.with_ctxt(source.export_ctxt); - - Some(VarDeclarator { - span: DUMMY_SP, - name: Pat::Ident(local.clone()), - init: Some(Box::new(Expr::Ident(imported))), - definite: false, - }) - } - _ => None, - }) - .collect::>(); - - for var in decls { - vars.push(var.into_module_item(injected_ctxt, "ExportInjector")); - } - } - - ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) - if export.src.value == source.src.value => - { - if !wrapped { - let export_ctxt = export.span.ctxt; - ctx.transitive_remap.insert(entry_export_ctxt, export_ctxt); - } - - if let Some(mut dep) = dep.take() { - if let Some(item) = remove_default_export(&mut dep) { - export_default_stmt = Some(item) - } - buf.extend(dep.into_items()); - } - } - - ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( - export @ NamedExport { src: Some(..), .. }, - )) if export.src.as_ref().unwrap().value == source.src.value => { - let namespace_name = export - .specifiers - .iter() - .filter_map(|specifier| match specifier { - ExportSpecifier::Namespace(ns) => Some(ns.name.clone()), - ExportSpecifier::Default(_) => None, - ExportSpecifier::Named(_) => None, - }) - .next(); - - if let Some(dep) = dep.take() { - buf.extend(dep.into_items()); - } - if let Some(stmt) = export_default_stmt.take() { - buf.push(stmt); - } - - if let Some(ns_name) = namespace_name { - buf.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( - NamedExport { - span: export.span, - src: None, - specifiers: vec![ExportSpecifier::Named(ExportNamedSpecifier { - span: DUMMY_SP, - orig: ns_name, - exported: None, - })], - type_only: false, - }, - ))); - } else { - buf.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( - NamedExport { - src: None, - ..export - }, - ))); - } +) { + entry.map_items_mut(|item| { + // + match item { + ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) + if export.src.value == source.src.value => + { + if !wrapped { + let export_ctxt = export.span.ctxt; + ctx.transitive_remap.insert(export_ctxt, entry_export_ctxt); } - - _ => buf.push(item), + *item = Stmt::Empty(EmptyStmt { span: DUMMY_SP }).into() + } + ModuleItem::ModuleDecl(ModuleDecl::Import(ref import)) + if import.src.value == source.src.value => + { + *item = Stmt::Empty(EmptyStmt { span: DUMMY_SP }).into() } - } - - buf - }); - - entry.inject_all(vars); - - match dep { - Some(dep) => Err(dep), - None => Ok(()), - } -} - -fn remove_default_export(dep: &mut Modules) -> Option { - let mut export_default_stmt = None; - - dep.retain_mut(|item| match item { - ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultExpr(..)) => { - export_default_stmt = Some(item.take()); - false - } - ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport { - span, specifiers, .. - })) => { - // - let mut default_specifer = None; - specifiers.retain_mut(|specifier| { - match specifier { - ExportSpecifier::Namespace(_) => {} - ExportSpecifier::Default(_) => {} - ExportSpecifier::Named(named) => match &named.exported { - Some(exported) => { - // - if exported.sym == js_word!("default") { - default_specifer = Some(named.orig.clone()); - return false; - } - } - None => { - // - if named.orig.sym == js_word!("default") { - default_specifer = Some(named.orig.take()); - - return false; - } - } - }, - } - - true - }); - match default_specifer { - Some(expr) => { - export_default_stmt = Some(ModuleItem::ModuleDecl( - ModuleDecl::ExportDefaultExpr(ExportDefaultExpr { - span: *span, - expr: Box::new(Expr::Ident(expr)), - }), - )); - !specifiers.is_empty() + ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + export @ NamedExport { src: Some(..), .. }, + )) if export.src.as_ref().unwrap().value == source.src.value => { + let namespace_name = export + .specifiers + .iter() + .filter_map(|specifier| match specifier { + ExportSpecifier::Namespace(ns) => Some(ns.name.clone()), + ExportSpecifier::Default(_) => None, + ExportSpecifier::Named(_) => None, + }) + .next(); + + if let Some(ns_name) = namespace_name { + *item = ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport { + span: export.span, + src: None, + specifiers: vec![ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ns_name, + exported: None, + })], + type_only: false, + })); + } else { + *item = ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport { + span: export.span, + specifiers: export.specifiers.take(), + src: None, + type_only: false, + })) } - None => true, } + + _ => {} } - _ => true, }); - export_default_stmt + entry.prepend_all(dep); } /// Converts @@ -560,27 +190,8 @@ fn remove_default_export(dep: &mut Modules) -> Option { /// => /// export { foo#7 as foo#5 } where #5 is mark of current entry. fn unexprt_as_var(modules: &mut Modules, dep_export_ctxt: SyntaxContext) { - let injected_ctxt = modules.injected_ctxt; - modules.map_items_mut(|n| { match n { - ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultExpr(export)) => { - let expr = replace( - &mut export.expr, - Box::new(Expr::Invalid(Invalid { span: DUMMY_SP })), - ); - - *n = VarDeclarator { - span: DUMMY_SP, - name: Pat::Ident(Ident::new( - "default".into(), - expr.span().with_ctxt(dep_export_ctxt), - )), - init: Some(expr), - definite: false, - } - .into_module_item(injected_ctxt, "UnexportAsVar"); - } ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( ref export @ NamedExport { src: None, .. }, )) => { diff --git a/bundler/src/bundler/chunk/merge.rs b/bundler/src/bundler/chunk/merge.rs index 8af0c2fa4d53..c5dcdb6b3061 100644 --- a/bundler/src/bundler/chunk/merge.rs +++ b/bundler/src/bundler/chunk/merge.rs @@ -65,8 +65,9 @@ where let mut module = self .get_module_for_merging(ctx, module_id, is_entry) - .map(|module| Modules::from(module, self.injected_ctxt)) - .with_context(|| format!("Failed to clone {:?} for merging", module_id))?; + .with_context(|| format!("failed to clone {:?} for merging", module_id))?; + + self.prepare(&info, &mut module); { let plan = ctx.plan.normal.get(&module_id); @@ -82,7 +83,7 @@ where // print_hygiene( // &format!("before merging deps: {}", info.fm.name), // &self.cm, - // &module, + // &module.clone().into(), // ); module = self.merge_deps(ctx, is_entry, module, plan, &info, !allow_circular)?; @@ -90,7 +91,7 @@ where // print_hygiene( // &format!("after merging deps: {}", info.fm.name), // &self.cm, - // &module, + // &module.clone().into(), // ); } @@ -119,30 +120,12 @@ where // Now we handle imports let mut module = if wrapped { - let mut module: Modules = self - .get_module_for_merging(ctx, dep_id, false) - .map(|module| Modules::from(module, self.injected_ctxt))?; + let mut module: Modules = self.get_module_for_merging(ctx, dep_id, false)?; module = self.wrap_esm(ctx, dep_id, module.into())?.into(); - - // Inject local_name = wrapped_esm_module_name - let module_ident = specifiers.iter().find_map(|specifier| match specifier { - Specifier::Namespace { - local, all: true, .. - } => Some(local.clone()), - _ => None, - }); + self.prepare(&dep_info, &mut module); let esm_id = self.scope.wrapped_esm_id(dep_id).unwrap(); - if let Some(module_ident) = &module_ident { - module.inject( - esm_id - .clone() - .assign_to(module_ident.clone()) - .into_module_item(injected_ctxt, "merge_direct_import"), - ); - } - let plan = ctx.plan.normal.get(&dep_id); let default_plan; let plan = match plan { @@ -188,37 +171,32 @@ where } else { let mut module = self.merge_modules(ctx, dep_id, false, true)?; - // print_hygiene("import: After meging deps of a dep", &self.cm, &module); + // print_hygiene( + // &format!( + // "import: Before handle_import_deps {:?}:{:?}", + // dep_info.local_ctxt(), + // dep_info.export_ctxt(), + // ), + // &self.cm, + // &module.clone().into(), + // ); self.handle_import_deps(ctx, &dep_info, &mut module, false); - // print_hygiene("import: After handle_import_deps", &self.cm, &module); + // print_hygiene( + // &format!( + // "import: After handle_import_deps {:?}:{:?}", + // dep_info.local_ctxt(), + // dep_info.export_ctxt(), + // ), + // &self.cm, + // &module.clone().into(), + // ); module }; - let mut var_decls = vars_from_exports(&dep_info, &module); + let var_decls = vars_from_exports(&dep_info, &module); module = module.fold_with(&mut Unexporter); - // Handle aliased imports - var_decls.extend(specifiers.iter().filter_map(|specifier| match specifier { - Specifier::Specific { - local, - alias: Some(alias), - } => { - let local = local.clone().into_ident(); - let alias = alias.clone().with_ctxt(dep_info.export_ctxt()).into_ident(); - - Some(VarDeclarator { - span: DUMMY_SP, - name: Pat::Ident(local), - init: Some(Box::new(Expr::Ident(alias))), - definite: false, - }) - } - // TODO - Specifier::Namespace { .. } => None, - _ => None, - })); - for var in var_decls { module.inject(var.into_module_item(injected_ctxt, "from_merge_direct_import")); } @@ -237,7 +215,7 @@ where let var_decls = vars_from_exports(&dep_info, &module); - module = module.fold_with(&mut Unexporter); + // module = module.fold_with(&mut Unexporter); for var in var_decls { module.inject(var.into_module_item(injected_ctxt, "from_merge_transitive_import")); @@ -379,7 +357,7 @@ where let mut targets = plan.chunks.clone(); for dep in deps { - let (is_export, source, dep, mut dep_module) = dep?; + let (is_export, source, dep, dep_module) = dep?; let dep_info = self.scope.get_module(dep.id).unwrap(); if let Some(idx) = targets.iter().position(|v| v.id == dep.id) { @@ -395,7 +373,7 @@ where if is_export { assert!(dep_info.is_es6, "export statements are es6-only"); - let res = inject_export( + inject_export( &mut module, ctx, info.export_ctxt(), @@ -404,13 +382,6 @@ where source.unwrap().clone(), ); - match res { - Ok(()) => {} - Err(..) => { - unreachable!("Merging as export when export statement does not exist?") - } - } - log::debug!( "Merged {} into {} as a reexport", dep_info.fm.name, @@ -425,7 +396,7 @@ where match dep.ty { DepType::Transitive => { - module.push_all(dep_module); + module.prepend_all(dep_module); log::debug!( "Merged {} into {} as a transitive es module", @@ -445,34 +416,6 @@ where // &module, // ); - // Replace import statement with module body - let res = inject_es_module( - &mut module, - dep_module, - dep_info.export_ctxt(), - match dep.ty { - DepType::Direct => true, - _ => false, - }, - ); - - dep_module = match res { - Ok(()) => { - log::debug!( - "Merged {} into {} as an es module", - dep_info.fm.name, - info.fm.name, - ); - // print_hygiene( - // &format!("ES6: {:?} <- {:?}", info.ctxt(), dep_info.ctxt()), - // &self.cm, - // &entry, - // ); - continue; - } - Err(dep) => dep, - }; - if info.is_es6 && dep_info.is_es6 { module.push_all(dep_module); continue; @@ -518,7 +461,7 @@ where _ctx: &Ctx, module_id: ModuleId, is_entry: bool, - ) -> Result { + ) -> Result { self.run(|| { let info = self.scope.get_module(module_id).unwrap(); @@ -532,7 +475,9 @@ where err: None, }); - Ok(entry) + let module = Modules::from(entry, self.injected_ctxt); + + Ok(module) }) } @@ -540,7 +485,7 @@ where /// /// This method does not care about orders of statement, and it's expected /// to be called before `sort`. - fn handle_export_stars(&self, ctx: &Ctx, entry: &mut Modules) { + fn handle_reexport_of_entry(&self, ctx: &Ctx, entry: &mut Modules) { let injected_ctxt = self.injected_ctxt; { @@ -571,6 +516,35 @@ where for stmt in entry.iter() { match stmt { + ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(export)) => { + for s in &export.specifiers { + match s { + ExportSpecifier::Namespace(_) => {} + ExportSpecifier::Default(_) => {} + ExportSpecifier::Named(named) => match &named.exported { + Some(exported) => { + let id: Id = exported.into(); + if declared_ids.contains(&id) { + continue; + } + + vars.push( + named + .orig + .clone() + .assign_to(exported.clone()) + .into_module_item( + injected_ctxt, + "finalize -> export to var", + ), + ); + } + None => {} + }, + } + } + } + ModuleItem::Stmt(Stmt::Decl(Decl::Var(decl))) => { let ids: Vec = find_ids(decl); @@ -705,11 +679,11 @@ where } fn finalize_merging_of_entry(&self, ctx: &Ctx, entry: &mut Modules) { - self.handle_export_stars(ctx, entry); + self.handle_reexport_of_entry(ctx, entry); // print_hygiene("before sort", &self.cm, &entry.clone().into()); - entry.sort(); + entry.sort(&self.cm); // print_hygiene("done", &self.cm, &entry.clone().into()); @@ -773,6 +747,304 @@ where // ); } + /// This method handles imports and exports. + /// + /// + /// Basically one module have two top-level contexts. One is for it's codes + /// and another is for exporting. This method connects two module by + /// injecting `const local_A = exported_B_from_foo;` + pub(crate) fn prepare(&self, info: &TransformedModule, module: &mut Modules) { + let injected_ctxt = self.injected_ctxt; + + if !info.is_es6 { + return; + } + + module.map_any_items(|items| { + let mut new = Vec::with_capacity(items.len() * 11 / 10); + + for item in items { + match item { + ModuleItem::ModuleDecl(ModuleDecl::Import(mut import)) => { + if let Some((src, _)) = info + .imports + .specifiers + .iter() + .find(|s| s.0.src.value == import.src.value) + { + if !self.scope.get_module(src.module_id).unwrap().is_es6 { + new.push(ModuleItem::ModuleDecl(ModuleDecl::Import(import))); + continue; + } + } + + // Imports are easy to handle. + for s in &import.specifiers { + match s { + ImportSpecifier::Named(s) => match &s.imported { + Some(imported) => { + new.push( + imported + .clone() + .assign_to(s.local.clone()) + .into_module_item( + injected_ctxt, + "prepare -> named import -> aliased", + ), + ); + } + None => {} + }, + ImportSpecifier::Default(s) => { + new.push( + Ident::new(js_word!("default"), import.span) + .assign_to(s.local.clone()) + .into_module_item( + injected_ctxt, + "prepare -> default import", + ), + ); + } + ImportSpecifier::Namespace(s) => { + if let Some((src, _)) = info + .imports + .specifiers + .iter() + .find(|s| s.0.src.value == import.src.value) + { + let esm_id = + self.scope.wrapped_esm_id(src.module_id).expect( + "If a namespace impoet specifier is preserved, it \ + means failutre of deblobbing and as a result \ + module should be marked as wrpaped esm", + ); + new.push( + esm_id + .clone() + .assign_to(s.local.clone()) + .into_module_item( + injected_ctxt, + "from_replace_import_specifiers: namespaced", + ), + ); + } + } + } + } + + import.specifiers.clear(); + new.push(ModuleItem::ModuleDecl(ModuleDecl::Import(import))); + } + ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(export)) => { + // At here, we create multiple items. + // + // One item is `const local_default = expr` and another one is + // `export { local_default as default }`. + // + // To allow using identifier of the declaration in the originsl module, we + // create `const local_default = orig_ident` if original identifier exists. + + let local = + Ident::new(js_word!("default"), DUMMY_SP.with_ctxt(info.local_ctxt())); + + match export.decl { + DefaultDecl::Class(c) => { + // + match c.ident { + Some(ident) => { + new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Class( + ClassDecl { + ident: ident.clone(), + class: c.class, + declare: false, + }, + )))); + + new.push(ident.assign_to(local.clone()).into_module_item( + injected_ctxt, + "prepare -> export default decl -> class -> with ident", + )) + } + None => { + let init = Expr::Class(c); + new.push(init.assign_to(local.clone()).into_module_item( + injected_ctxt, + "prepare -> export default decl -> class -> without \ + ident", + )); + } + } + } + DefaultDecl::Fn(f) => { + // + match f.ident { + Some(ident) => { + new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { + ident: ident.clone(), + function: f.function, + declare: false, + })))); + + new.push(ident.assign_to(local.clone()).into_module_item( + injected_ctxt, + "prepare -> export default decl -> function -> with \ + ident", + )) + } + None => { + let init = Expr::Fn(f); + + new.push(init.assign_to(local.clone()).into_module_item( + injected_ctxt, + "prepare -> export default decl -> function -> \ + without ident", + )); + } + } + } + DefaultDecl::TsInterfaceDecl(_) => continue, + } + + // Create `export { local_default as default }` + let specifier = ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: local, + exported: Some(Ident::new( + js_word!("default"), + DUMMY_SP.with_ctxt(info.export_ctxt()), + )), + }); + new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: export.span.with_ctxt(injected_ctxt), + specifiers: vec![specifier], + src: None, + type_only: false, + }, + ))); + } + + ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultExpr(export)) => { + // At here, we create two items. + // + // One item is `const local_default = expr` and the + // other is `export { local_default as default }`. + + // TODO: Check if we really need this. + + let local = + Ident::new(js_word!("default"), DUMMY_SP.with_ctxt(info.local_ctxt())); + + // Create `const local_default = expr` + new.push( + export + .expr + .assign_to(local.clone()) + .into_module_item(injected_ctxt, "prepare -> export default expr"), + ); + + // Create `export { local_default as default }` + let specifier = ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: local, + exported: Some(Ident::new( + js_word!("default"), + DUMMY_SP.with_ctxt(info.export_ctxt()), + )), + }); + new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: export.span.with_ctxt(injected_ctxt), + specifiers: vec![specifier], + src: None, + type_only: false, + }, + ))); + } + + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(export)) => { + // Idea is almost same as above. But we uses symbol of the declaration + // instead of using `default`. + + let local = match export.decl { + Decl::Class(c) => { + let i = c.ident.clone(); + new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Class(c)))); + + i + } + Decl::Fn(f) => { + let i = f.ident.clone(); + new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f)))); + + i + } + Decl::Var(v) => { + let ids: Vec = find_ids(&v); + // + + new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Var(v)))); + + new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: export.span.with_ctxt(injected_ctxt), + specifiers: ids + .into_iter() + .map(|id| { + let exported = Ident::new( + id.sym.clone(), + id.span.with_ctxt(info.export_ctxt()), + ); + + ExportNamedSpecifier { + span: DUMMY_SP, + orig: id, + exported: Some(exported), + } + }) + .map(ExportSpecifier::Named) + .collect(), + src: None, + type_only: false, + }, + ))); + continue; + } + + Decl::TsInterface(_) + | Decl::TsTypeAlias(_) + | Decl::TsEnum(_) + | Decl::TsModule(_) => continue, + }; + + // Create `export { local_ident as exported_ident }` + let exported = + Ident::new(local.sym.clone(), local.span.with_ctxt(info.export_ctxt())); + let specifier = ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: local, + exported: Some(exported), + }); + new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: export.span.with_ctxt(injected_ctxt), + specifiers: vec![specifier], + src: None, + type_only: false, + }, + ))); + } + + _ => { + new.push(item); + } + } + } + + new + }); + } + pub(super) fn replace_import_specifiers(&self, info: &TransformedModule, module: &mut Modules) { let injected_ctxt = self.injected_ctxt; @@ -875,8 +1147,6 @@ where ) { let injected_ctxt = self.injected_ctxt; - self.replace_import_specifiers(info, module); - let mut vars = vec![]; for orig_stmt in module.iter_mut() { @@ -912,20 +1182,41 @@ where } ExportSpecifier::Named(named) => match &named.exported { Some(exported) => { - if named.orig.span.ctxt != info.export_ctxt() + assert_ne!( + named.orig.span.ctxt, exported.span.ctxt, + "While handling imports, all named export \ + specifiers should be modified to reflect syntax \ + context correctly by previous passes" + ); + + vars.push( + named + .orig + .clone() + .assign_to(exported.clone()) + .into_module_item( + injected_ctxt, + &format!( + "import -> named alias -> prepared: {}", + info.fm.name + ), + ), + ); + + if exported.span.ctxt != info.export_ctxt() && exported.sym != js_word!("default") { let mut lhs = exported.clone(); lhs.span = lhs.span.with_ctxt(info.export_ctxt()); vars.push( - named - .orig + exported .clone() .assign_to(lhs) .into_module_item( injected_ctxt, &format!( - "import_deps_named_alias of {}", + "import -> named alias -> export: \ + {}", info.fm.name ), ), @@ -1251,79 +1542,6 @@ impl Fold for Unexporter { } } -/// Returns `Err(dep)` on error. -fn inject_es_module( - entry: &mut Modules, - dep: Modules, - dep_export_ctxt: SyntaxContext, - is_direct: bool, -) -> Result<(), Modules> { - let injected_ctxt = entry.injected_ctxt; - - let mut vars = vec![]; - let mut dep = Some(dep); - - entry.map_any_items(|items| { - if dep.is_none() { - return items; - } - - let mut buf = vec![]; - - for item in items { - // - match item { - ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { - span, specifiers, .. - })) if span.ctxt == dep_export_ctxt => { - if let Some(dep) = dep.take() { - buf.extend(dep.into_items()); - } - - if !is_direct { - let decls = specifiers - .iter() - .filter_map(|specifier| match specifier { - ImportSpecifier::Named(ImportNamedSpecifier { - local, - imported: Some(imported), - .. - }) => { - let mut imported = imported.clone(); - imported.span = imported.span.with_ctxt(dep_export_ctxt); - - Some(VarDeclarator { - span: DUMMY_SP, - name: Pat::Ident(local.clone()), - init: Some(Box::new(Expr::Ident(imported))), - definite: false, - }) - } - _ => None, - }) - .collect::>(); - - for var in decls { - vars.push(var.into_module_item(injected_ctxt, "Es6ModuleInjector")); - } - } - } - - _ => buf.push(item), - } - } - - buf - }); - - entry.inject_all(vars); - - match dep { - Some(dep) => Err(dep), - None => Ok(()), - } -} - struct ImportMetaHandler<'a, 'b> { file: &'a FileName, hook: &'a Box, diff --git a/bundler/src/bundler/export.rs b/bundler/src/bundler/export.rs index 3072f3bb809a..277c1265fa42 100644 --- a/bundler/src/bundler/export.rs +++ b/bundler/src/bundler/export.rs @@ -45,7 +45,7 @@ pub(super) struct RawExports { } #[derive(Debug, Default)] -pub(super) struct Exports { +pub(crate) struct Exports { pub items: Vec, pub reexports: Vec<(Source, Vec)>, } diff --git a/bundler/src/bundler/helpers/mod.rs b/bundler/src/bundler/helpers/mod.rs index 0bf47f02aa8d..50611a36f2fb 100644 --- a/bundler/src/bundler/helpers/mod.rs +++ b/bundler/src/bundler/helpers/mod.rs @@ -6,7 +6,7 @@ use swc_ecma_parser::{lexer::Lexer, Parser, StringInput}; use swc_ecma_utils::{drop_span, prepend_stmts}; #[derive(Debug, Default)] -pub(super) struct Helpers { +pub(crate) struct Helpers { /// `__spack_require__` pub require: AtomicBool, } diff --git a/bundler/src/bundler/keywords.rs b/bundler/src/bundler/keywords.rs index 37f9ecd52b7f..ef7ec02e9eae 100644 --- a/bundler/src/bundler/keywords.rs +++ b/bundler/src/bundler/keywords.rs @@ -35,6 +35,43 @@ impl KeywordRenamer { impl VisitMut for KeywordRenamer { noop_visit_mut_type!(); + fn visit_mut_fn_decl(&mut self, f: &mut FnDecl) { + f.function.visit_mut_with(self); + if let Some(renamed) = self.renamed(&f.ident) { + f.ident = renamed; + } + } + + fn visit_mut_class_decl(&mut self, c: &mut ClassDecl) { + c.class.visit_mut_with(self); + if let Some(renamed) = self.renamed(&c.ident) { + c.ident = renamed; + } + } + + fn visit_mut_prop(&mut self, n: &mut Prop) { + match n { + Prop::Shorthand(i) => { + if let Some(renamed) = self.renamed(&i) { + *n = Prop::KeyValue(KeyValueProp { + key: PropName::Ident(i.clone()), + value: Box::new(Expr::Ident(renamed)), + }); + } + } + _ => { + n.visit_mut_children_with(self); + } + } + } + + fn visit_mut_assign_pat_prop(&mut self, n: &mut AssignPatProp) { + if let Some(renamed) = self.renamed(&n.key) { + n.key = renamed; + } + n.value.visit_mut_with(self); + } + fn visit_mut_pat(&mut self, n: &mut Pat) { match n { Pat::Ident(n) => { diff --git a/bundler/src/bundler/load.rs b/bundler/src/bundler/load.rs index 937a7048d44d..840ea87d786e 100644 --- a/bundler/src/bundler/load.rs +++ b/bundler/src/bundler/load.rs @@ -21,7 +21,7 @@ use swc_ecma_transforms::resolver_with_mark; use swc_ecma_visit::{noop_visit_type, FoldWith, Node, Visit, VisitWith}; /// Module after applying transformations. #[derive(Debug, Clone)] -pub(super) struct TransformedModule { +pub(crate) struct TransformedModule { pub id: ModuleId, pub fm: Lrc, pub module: Lrc, @@ -366,14 +366,14 @@ where } #[derive(Debug, Default)] -pub(super) struct Imports { +pub(crate) struct Imports { /// If imported ids are empty, it is a side-effect import. pub specifiers: Vec<(Source, Vec)>, } /// Clone is relatively cheap #[derive(Debug, Clone, Is)] -pub(super) enum Specifier { +pub(crate) enum Specifier { Specific { local: Id, alias: Option, @@ -386,7 +386,7 @@ pub(super) enum Specifier { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(super) struct Source { +pub(crate) struct Source { pub is_loaded_synchronously: bool, pub is_unconditional: bool, diff --git a/bundler/src/bundler/modules/sort.rs b/bundler/src/bundler/modules/sort/mod.rs similarity index 65% rename from bundler/src/bundler/modules/sort.rs rename to bundler/src/bundler/modules/sort/mod.rs index b219a0f0c854..36e5acc92bae 100644 --- a/bundler/src/bundler/modules/sort.rs +++ b/bundler/src/bundler/modules/sort/mod.rs @@ -11,6 +11,8 @@ use std::iter::from_fn; use std::mem::take; use std::ops::Range; use swc_atoms::js_word; +use swc_common::sync::Lrc; +use swc_common::SourceMap; use swc_common::Spanned; use swc_common::DUMMY_SP; use swc_ecma_ast::*; @@ -20,6 +22,7 @@ use swc_ecma_visit::{noop_visit_type, Node, Visit, VisitWith}; type StmtDepGraph = self::graph::StmtDepGraph; mod graph; + /// Is dependancy between nodes hard? #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] enum Required { @@ -31,7 +34,7 @@ enum Required { } impl Modules { - pub fn sort(&mut self) { + pub fn sort(&mut self, _cm: &Lrc) { let injected_ctxt = self.injected_ctxt; { let mut modules = take(&mut self.modules); @@ -55,7 +58,6 @@ impl Modules { }); let mut new = vec![]; - let mut graph = StmtDepGraph::default(); new.extend(self.prepended.drain(..)); let mut module_starts = vec![]; @@ -91,114 +93,17 @@ impl Modules { } new.extend(self.injected.drain(..)); - let mut declared_by = HashMap::>::default(); - let mut uninitialized_ids = HashMap::::new(); - - for (idx, item) in new.iter().enumerate() { - graph.add_node(idx); - - // We start by calculating ids created by statements. Note that we don't need to - // analyze bodies of functions nor members of classes, because it's not - // evaludated until they are called. - - match item { - // We only check declarations because ids are created by declarations. - ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { decl, .. })) - | ModuleItem::Stmt(Stmt::Decl(decl)) => { - // - match decl { - Decl::Class(ClassDecl { ident, .. }) | Decl::Fn(FnDecl { ident, .. }) => { - // eprintln!("`{}` declares {:?}`", idx, Id::from(ident)); - declared_by.entry(Id::from(ident)).or_default().push(idx); - } - Decl::Var(vars) => { - for var in &vars.decls { - // - let ids: Vec = find_ids(&var.name); - for id in ids { - if var.init.is_none() { - uninitialized_ids.insert(id.clone(), idx); - } - - // eprintln!("`{}` declares {:?}`", idx, id); - declared_by.entry(id).or_default().push(idx); - } - } - } - _ => {} - } - } - _ => {} - } + // print_hygiene( + // "before sort", + // cm, + // &Module { + // span: DUMMY_SP, + // body: new.clone(), + // shebang: None, + // }, + // ); - { - // Find extra initializations. - let mut v = PrototypeUsageFinter::default(); - item.visit_with(&Invalid { span: DUMMY_SP }, &mut v); - - for id in v.accessed { - if let Some(declarator_indexes) = declared_by.get(&id) { - for &declarator_index in declarator_indexes { - if declarator_index != idx { - graph.add_edge(idx, declarator_index, Required::Always); - // eprintln!("`{}` depends on `{}: {:?}`", idx, - // declarator_index, &id); - } - } - - // eprintln!("`{}` declares {:?}`", idx, id); - declared_by.entry(id).or_default().push(idx); - } - } - } - } - - // Handle uninitialized variables - // - // Compiled typescript enum is not initialized by declaration - // - // var Status; - // (function(Status){})(Status) - for (uninit_id, start_idx) in uninitialized_ids { - for (idx, item) in new.iter().enumerate().filter(|(idx, _)| *idx > start_idx) { - let mut finder = InitializerFinder { - ident: uninit_id.clone(), - found: false, - in_complex: false, - }; - item.visit_with(&Invalid { span: DUMMY_SP }, &mut finder); - if finder.found { - declared_by.entry(uninit_id).or_default().push(idx); - break; - } - } - } - - for (idx, item) in new.iter().enumerate() { - // We then calculate which ids a statement require to be executed. - // Again, we don't need to analyze non-top-level idents because they - // are not evaluated while lpoading module. - - let mut visitor = RequirementCalculartor::default(); - - item.visit_with(&Invalid { span: DUMMY_SP }, &mut visitor); - - for (id, kind) in visitor.required_ids { - if let Some(declarator_indexes) = declared_by.get(&id) { - for &declarator_index in declarator_indexes { - if declarator_index != idx { - graph.add_edge(idx, declarator_index, kind); - // eprintln!("`{}` depends on `{}: {:?}`", idx, declarator_index, id); - if cfg!(debug_assertions) { - let deps: Vec<_> = - graph.neighbors_directed(idx, Dependancies).collect(); - assert!(deps.contains(&declarator_index)); - } - } - } - } - } - } + let mut graph = calc_deps(&new); // Now graph contains enough information to sort statements. let mut orders = vec![]; @@ -219,14 +124,15 @@ impl Modules { buf.push(stmt) } - *self = Modules::from( - Module { - span: DUMMY_SP, - body: buf, - shebang: None, - }, - injected_ctxt, - ); + let module = Module { + span: DUMMY_SP, + body: buf, + shebang: None, + }; + + // print_hygiene("after sort", cm, &module); + + *self = Modules::from(module, injected_ctxt); } } @@ -274,19 +180,21 @@ fn iter<'a>( // eprintln!("Done: {}", idx); continue; } - // dbg!(idx); + let is_free = free.contains(&idx); + + // dbg!(idx, is_free); // match &stmts[idx] { // ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) => { // let ids: Vec = find_ids(&var.decls); - // eprintln!("({}) Declare: `{:?}`", idx, ids); + // eprintln!("(`{}`) Declare: `{:?}`", idx, ids); // } // ModuleItem::Stmt(Stmt::Decl(Decl::Class(cls))) => { - // eprintln!("({}) Declare: `{:?}`", idx, Id::from(&cls.ident)); + // eprintln!("(`{}`) Declare: `{:?}`", idx, Id::from(&cls.ident)); // } // ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f))) => { - // eprintln!("({}) Declare: `{:?}`", idx, Id::from(&f.ident)); + // eprintln!("(`{}`) Declare: `{:?}`", idx, Id::from(&f.ident)); // } - // item => eprintln!("({}) Stmt: {:?}", idx, item), + // _ => eprintln!("(`{}`) Stmt", idx,), // } let current_range = same_module_ranges @@ -330,6 +238,14 @@ fn iter<'a>( let deps = graph .neighbors_directed(idx, Dependancies) .filter(|dep| { + let declared_in_same_module = match ¤t_range { + Some(v) => v.contains(&dep), + None => false, + }; + if declared_in_same_module { + return false; + } + // Exlcude emitted items !done.contains(dep) }) @@ -355,12 +271,6 @@ fn iter<'a>( } } - if let Some(range) = ¤t_range { - if dep > idx && range.contains(&dep) { - continue; - } - } - deps_to_push.push(dep); } @@ -379,9 +289,6 @@ fn iter<'a>( } } } - let is_free = free.contains(&idx); - - // dbg!(is_free); if is_free { let dependants = graph @@ -389,7 +296,7 @@ fn iter<'a>( .collect::>(); for dependant in dependants { - if !done.contains(&dependant) { + if !done.contains(&dependant) && free.contains(&dependant) { stack.push_front(dependant); } } @@ -408,8 +315,10 @@ fn iter<'a>( // dbg!(&dependants); + // We only emit free items because we want to emit statements from same module + // to emitted closedly. for dependant in dependants { - if !done.contains(&dependant) { + if !done.contains(&dependant) && free.contains(&dependant) { stack.push_front(dependant); } } @@ -422,7 +331,7 @@ fn iter<'a>( }; // We should respect original order of statements within a module. - for preceding in current_range { + for preceding in current_range.clone() { // We should select first statement in module which is not emitted yet. if done.contains(&preceding) { continue; @@ -437,7 +346,7 @@ fn iter<'a>( if !moves.insert((idx, preceding)) { // idx = preceding; - break; + continue; } let dependants = graph @@ -446,8 +355,10 @@ fn iter<'a>( // dbg!(&dependants); + // We only emit free items because we want to emit statements from same module + // to emitted closedly. for dependant in dependants { - if !done.contains(&dependant) { + if !done.contains(&dependant) && free.contains(&dependant) { stack.push_front(dependant); } } @@ -458,6 +369,16 @@ fn iter<'a>( continue 'main; } + // Prefer inserting module as a whole. + let next = idx + 1; + if current_range.contains(&next) { + if moves.insert((idx, next)) { + if !done.contains(&next) { + stack.push_front(next); + } + } + } + graph.remove_node(idx); done.insert(idx); return Some(idx); @@ -469,16 +390,52 @@ fn iter<'a>( /// Using prototype should be treated as an initialization. #[derive(Default)] -struct PrototypeUsageFinter { +struct FieldInitFinter { in_object_assign: bool, in_rhs: bool, accessed: HashSet, } -impl Visit for PrototypeUsageFinter { +impl FieldInitFinter { + fn check_lhs_of_assign(&mut self, lhs: &PatOrExpr) { + match lhs { + PatOrExpr::Expr(e) => { + self.check_lhs_expr_of_assign(&e); + } + PatOrExpr::Pat(pat) => match &**pat { + Pat::Expr(e) => { + self.check_lhs_expr_of_assign(&e); + } + _ => {} + }, + } + } + fn check_lhs_expr_of_assign(&mut self, lhs: &Expr) { + match lhs { + Expr::Member(m) => { + let obj = match &m.obj { + ExprOrSuper::Super(_) => return, + ExprOrSuper::Expr(obj) => &**obj, + }; + + match obj { + Expr::Ident(i) => { + self.accessed.insert(i.into()); + } + Expr::Member(..) => self.check_lhs_expr_of_assign(&obj), + _ => {} + } + } + _ => {} + } + } +} + +impl Visit for FieldInitFinter { fn visit_assign_expr(&mut self, e: &AssignExpr, _: &dyn Node) { let old = self.in_rhs; e.left.visit_with(e, self); + self.check_lhs_of_assign(&e.left); self.in_rhs = true; e.right.visit_with(e, self); @@ -608,6 +565,10 @@ impl Visit for InitializerFinder { #[derive(Default)] struct RequirementCalculartor { required_ids: IndexSet<(Id, Required)>, + /// While bundling, there can be two bindings with same name and syntax + /// context, in case of wrapped es modules. We exclude them from dependency + /// graph. + excluded: IndexSet, in_weak: bool, in_var_decl: bool, @@ -684,25 +645,28 @@ impl Visit for RequirementCalculartor { let in_var_decl = self.in_var_decl; self.in_var_decl = true; + if self.in_weak { + let ids: Vec = find_ids(&var.name); + self.excluded.extend(ids); + } + var.visit_children_with(self); self.in_var_decl = in_var_decl; } fn visit_expr(&mut self, expr: &Expr, _: &dyn Node) { - let in_var_decl = self.in_var_decl; - self.in_var_decl = false; - match expr { Expr::Ident(i) => { + if self.in_var_decl && self.in_assign_lhs { + return; + } self.insert(i.into()); } _ => { expr.visit_children_with(self); } } - - self.in_var_decl = in_var_decl; } fn visit_prop(&mut self, prop: &Prop, _: &dyn Node) { @@ -722,3 +686,156 @@ impl Visit for RequirementCalculartor { } } } + +fn calc_deps(new: &[ModuleItem]) -> StmtDepGraph { + let mut graph = StmtDepGraph::default(); + + let mut declared_by = HashMap::>::default(); + let mut uninitialized_ids = HashMap::::new(); + + for (idx, item) in new.iter().enumerate() { + graph.add_node(idx); + + // We start by calculating ids created by statements. Note that we don't need to + // analyze bodies of functions nor members of classes, because it's not + // evaludated until they are called. + + match item { + // We only check declarations because ids are created by declarations. + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { decl, .. })) + | ModuleItem::Stmt(Stmt::Decl(decl)) => { + // + match decl { + Decl::Class(ClassDecl { ident, .. }) | Decl::Fn(FnDecl { ident, .. }) => { + // eprintln!("Decl: `{}` declares {:?}`", idx, Id::from(ident)); + declared_by.entry(Id::from(ident)).or_default().push(idx); + } + Decl::Var(vars) => { + for var in &vars.decls { + // + let ids: Vec = find_ids(&var.name); + for id in ids { + if var.init.is_none() { + uninitialized_ids.insert(id.clone(), idx); + } + + // eprintln!("Decl: `{}` declares {:?}`", idx, id); + declared_by.entry(id).or_default().push(idx); + } + } + } + _ => {} + } + } + _ => {} + } + + { + // Find extra initializations. + let mut v = FieldInitFinter::default(); + item.visit_with(&Invalid { span: DUMMY_SP }, &mut v); + + for id in v.accessed { + if let Some(declarator_indexes) = declared_by.get(&id) { + // let idx_decl = match &item { + // ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) => { + // let ids: Vec = find_ids(&var.decls); + // format!("`{:?}`", ids) + // } + // ModuleItem::Stmt(Stmt::Decl(Decl::Class(c))) => { + // format!("{}{:?}", c.ident.sym, c.ident.span.ctxt) + // } + // ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f))) => { + // format!("{}{:?}", f.ident.sym, f.ident.span.ctxt) + // } + // _ => String::from(""), + // }; + + for &declarator_index in declarator_indexes { + if declarator_index != idx { + graph.add_edge(idx, declarator_index, Required::Always); + // eprintln!( + // "Field init: `{}` ({}) depends on `{}`: + // {:?}", + // idx, idx_decl, declarator_index, &id + // ); + } + } + + // eprintln!("`{}` declares {:?}`", idx, id); + declared_by.entry(id).or_default().push(idx); + } + } + } + } + + // Handle uninitialized variables + // + // Compiled typescript enum is not initialized by declaration + // + // var Status; + // (function(Status){})(Status) + for (uninit_id, start_idx) in uninitialized_ids { + for (idx, item) in new.iter().enumerate().filter(|(idx, _)| *idx > start_idx) { + let mut finder = InitializerFinder { + ident: uninit_id.clone(), + found: false, + in_complex: false, + }; + item.visit_with(&Invalid { span: DUMMY_SP }, &mut finder); + if finder.found { + declared_by.entry(uninit_id).or_default().push(idx); + break; + } + } + } + + for (idx, item) in new.iter().enumerate() { + // We then calculate which ids a statement require to be executed. + // Again, we don't need to analyze non-top-level idents because they + // are not evaluated while lpoading module. + + let mut visitor = RequirementCalculartor::default(); + + item.visit_with(&Invalid { span: DUMMY_SP }, &mut visitor); + + for (id, kind) in visitor.required_ids { + if visitor.excluded.contains(&id) { + continue; + } + + if let Some(declarator_indexes) = declared_by.get(&id) { + for &declarator_index in declarator_indexes { + if declarator_index != idx { + // let idx_decl = match &item { + // ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) => { + // let ids: Vec = find_ids(&var.decls); + // format!("`{:?}`", ids) + // } + // ModuleItem::Stmt(Stmt::Decl(Decl::Class(c))) => { + // format!("{}{:?}", c.ident.sym, c.ident.span.ctxt) + // } + // ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f))) => { + // format!("{}{:?}", f.ident.sym, f.ident.span.ctxt) + // } + // _ => String::from(""), + // }; + + graph.add_edge(idx, declarator_index, kind); + // eprintln!( + // "`{}` ({}) depends on `{}`: {:?}", + // idx, idx_decl, declarator_index, &id + // ); + if cfg!(debug_assertions) { + let deps: Vec<_> = + graph.neighbors_directed(idx, Dependancies).collect(); + assert!(deps.contains(&declarator_index)); + } + } + } + } + } + } + + graph +} diff --git a/bundler/src/bundler/modules/sort/tests.rs b/bundler/src/bundler/modules/sort/tests.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/bundler/src/bundler/modules/tests.rs b/bundler/src/bundler/modules/tests.rs deleted file mode 100644 index 4fc937a4cbc9..000000000000 --- a/bundler/src/bundler/modules/tests.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::bundler::modules::Modules; -use crate::bundler::tests::suite; -use crate::debug::print_hygiene; -use swc_ecma_ast::Module; -use swc_ecma_utils::drop_span; - -fn assert_sorted(src: &[&str], res: &str) { - suite().run(|t| { - let mut modules = Modules::empty(t.bundler.injected_ctxt); - - for src in src { - let actual: Module = drop_span(t.parse(src)); - modules.push_all(Modules::from(actual, t.bundler.injected_ctxt)); - } - - modules.sort(); - let actual: Module = modules.into(); - - let expected = drop_span(t.parse(res)); - - if actual == expected { - return Ok(()); - } - - print_hygiene("actual", &t.cm, &actual); - print_hygiene("expected", &t.cm, &expected); - panic!() - }); -} - -#[test] -fn sort_001() { - assert_sorted( - &["_9[0] = 133;", "const _9 = new ByteArray(32);"], - " - const _9 = new ByteArray(32); - _9[0] = 133; - ", - ) -} - -#[test] -fn sort_002() { - assert_sorted( - &[ - " - const mod = (function(){ - const A = v; - }()); - ", - "const v = 5;", - ], - " - const v = 5; - const mod = (function(){ - const A = v; - }()); - ", - ) -} - -#[test] -fn sort_003() { - assert_sorted( - &[ - "class Constraint extends serialization.Serializable {}", - "const serialization = {};", - ], - " - const serialization = {}; - class Constraint extends serialization.Serializable { - } - ", - ); -} - -#[test] -fn sort_004() { - assert_sorted( - &["use(global);", "const global = getGlobal();"], - " - const global = getGlobal(); - use(global); - ", - ); -} - -#[test] -fn sort_005() { - assert_sorted( - &[ - "use(a);", - " - const a = new A(); - export const b = 1; - ", - " - use(b); - export class A {} - ", - ], - " - export class A { - } - const a = new A(); - export const b = 1; - use(b); - use(a); - ", - ); -} diff --git a/bundler/src/bundler/modules/tests/mod.rs b/bundler/src/bundler/modules/tests/mod.rs new file mode 100644 index 000000000000..04bc4e94289c --- /dev/null +++ b/bundler/src/bundler/modules/tests/mod.rs @@ -0,0 +1,485 @@ +use crate::bundler::modules::Modules; +use crate::bundler::tests::suite; +use crate::debug::print_hygiene; +use swc_ecma_ast::Module; +use swc_ecma_utils::drop_span; +use testing::assert_eq; + +fn assert_sorted(src: &[&str], res: &str) { + let mut s = suite(); + + for (i, src) in src.iter().enumerate() { + s = s.file(&format!("{}.js", i), src); + } + s.run(|t| { + let mut modules = Modules::empty(t.bundler.injected_ctxt); + + for (i, _) in src.iter().enumerate() { + let info = t.module(&format!("{}.js", i)); + let actual: Module = drop_span((*info.module).clone()); + + let mut module = Modules::from(actual, t.bundler.injected_ctxt); + + t.bundler.prepare(&info, &mut module); + modules.push_all(module); + } + + modules.sort(&t.cm); + let actual: Module = modules.into(); + + let expected = drop_span(t.parse(res)); + + if actual == expected { + return Ok(()); + } + + print_hygiene("actual", &t.cm, &actual); + print_hygiene("expected", &t.cm, &expected); + + assert_eq!(actual, expected); + panic!() + }); +} + +fn assert_sorted_with_free(src: &[&str], free: &str, res: &str) { + suite().run(|t| { + let mut modules = Modules::empty(t.bundler.injected_ctxt); + + let free: Module = drop_span(t.parse(free)); + modules.inject_all(free.body); + + for src in src { + let actual: Module = drop_span(t.parse(src)); + modules.push_all(Modules::from(actual, t.bundler.injected_ctxt)); + } + + modules.sort(&t.cm); + let actual: Module = drop_span(modules.into()); + + let expected = drop_span(t.parse(res)); + + if actual == expected { + return Ok(()); + } + + print_hygiene("actual", &t.cm, &actual); + print_hygiene("expected", &t.cm, &expected); + assert_eq!(actual, expected); + panic!() + }); +} + +#[test] +fn sort_001() { + assert_sorted( + &["_9[0] = 133;", "const _9 = new ByteArray(32);"], + " + const _9 = new ByteArray(32); + _9[0] = 133; + ", + ) +} + +#[test] +fn sort_002() { + assert_sorted( + &[ + " + const mod = (function(){ + const A = v; + }()); + ", + "const v = 5;", + ], + " + const v = 5; + const mod = (function(){ + const A = v; + }()); + ", + ) +} + +#[test] +fn sort_003() { + assert_sorted( + &[ + "class Constraint extends serialization.Serializable {}", + "const serialization = {};", + ], + " + const serialization = {}; + class Constraint extends serialization.Serializable { + } + ", + ); +} + +#[test] +fn sort_004() { + assert_sorted( + &["use(global);", "const global = getGlobal();"], + " + const global = getGlobal(); + use(global); + ", + ); +} + +#[test] +fn sort_005() { + assert_sorted( + &[ + "use(a);", + " + const a = new A(); + const b = 1; + ", + " + use(b); + class A {} + ", + ], + " + class A { + } + const a = new A(); + const b = 1; + use(b); + use(a); + ", + ); +} + +#[test] +fn deno_jszip_01() { + assert_sorted( + &[ + "use(a);", + " + const a = {}; + a.foo = 1; + ", + ], + " + const a = {}; + a.foo = 1; + use(a) + ", + ); +} + +#[test] +fn deno_jszip_02() { + assert_sorted( + &[ + "X()", + " + const Q = 'undefined' != typeof globalThis ? globalThis : 'undefined' != typeof self ? \ + self : global; + ", + " + function X() { + console.log(Q.A) + } + ", + ], + " + const Q = 'undefined' != typeof globalThis ? globalThis : 'undefined' != typeof self ? \ + self : global; + function X() { + console.log(Q.A) + } + X() + ", + ); +} + +#[test] +fn deno_jszip_03() { + assert_sorted( + &[ + "const v = X()", + " + const Q = 'undefined' != typeof globalThis ? globalThis : 'undefined' != typeof self ? \ + self : global; + function X() { + console.log(Q.A) + } + ", + ], + " + const Q = 'undefined' != typeof globalThis ? globalThis : 'undefined' != typeof self ? \ + self : global; + function X() { + console.log(Q.A) + } + const v = X() + ", + ); +} + +#[test] +fn sort_006() { + assert_sorted( + &[ + "use(b)", + " + const b, a = b = {}; + a.env = {}; + ", + ], + " + const b, a = b = {}; + a.env = {}; + use(b); + ", + ); +} + +#[test] +fn sort_007() { + assert_sorted_with_free( + &[ + " + var e, o = e = {}; + var T = e; + e.env = {}; + ", + " + if (h$1.env.NODE_DEBUG) { + } + ", + ], + " + const h325 = T; + const h$1 = h325; + ", + " + var e, o = e = {}; + var T = e; + e.env = {}; + const h325 = T; + const h$1 = h325; + if (h$1.env.NODE_DEBUG) { + } + ", + ); +} + +#[test] +fn sort_008() { + assert_sorted_with_free( + &[ + " + var e, o = e = {}; + o.env = {} + var T = e; + ", + " + use(h); + ", + ], + " + const h = T; + ", + " + var e, o = e = {}; + o.env = {} + var T = e; + const h = T; + use(h); + ", + ); +} + +#[test] +fn sort_009() { + assert_sorted_with_free( + &[ + " + use(h); + ", + " + var e, o = e = {}; + o.env = {} + var T = e; + ", + ], + " + const h = T; + ", + " + var e, o = e = {}; + o.env = {} + var T = e; + const h = T; + use(h); + ", + ); +} + +#[test] +fn sort_010() { + assert_sorted( + &[" + class AbstractBufBase {} + class BufWriter extends AbstractBufBase {} + "], + " + class AbstractBufBase {} + class BufWriter extends AbstractBufBase {} + ", + ); +} + +#[test] +fn sort_011() { + assert_sorted( + &[ + "use(BufWriter)", + "use(BufWriterSync)", + " + class AbstractBufBase {} + class BufWriter extends AbstractBufBase {} + class BufWriterSync extends AbstractBufBase { } + ", + ], + " + class AbstractBufBase { + } + class BufWriter extends AbstractBufBase { + } + class BufWriterSync extends AbstractBufBase { + } + use(BufWriter); + use(BufWriterSync); + ", + ); +} + +#[test] +fn sort_012() { + assert_sorted( + &[ + "use(isWindows)", + "use(NATIVE_OS)", + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + ", + ], + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + use(isWindows); + use(NATIVE_OS); + ", + ); +} + +#[test] +fn sort_013() { + assert_sorted( + &[ + "use(isWindows)", + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + ", + ], + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + use(isWindows); + ", + ); +} + +#[test] +fn sort_014() { + assert_sorted( + &[ + "use(NATIVE_OS)", + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + ", + ], + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + use(NATIVE_OS) + ", + ); +} + +#[test] +fn sort_015() { + assert_sorted( + &[ + " + use(isWindows) + use(NATIVE_OS) + ", + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + ", + ], + " + let NATIVE_OS = 'linux'; + const navigator = globalThis.navigator; + if (globalThis.Deno != null) { + NATIVE_OS = Deno.build.os; + } else if (navigator?.appVersion?.includes?.('Win') ?? false) { + NATIVE_OS = 'windows'; + } + const isWindows = NATIVE_OS == 'windows'; + use(isWindows); + use(NATIVE_OS); + ", + ); +} diff --git a/bundler/src/bundler/tests.rs b/bundler/src/bundler/tests.rs index 3468dd6743f6..b8fd3d851c4b 100644 --- a/bundler/src/bundler/tests.rs +++ b/bundler/src/bundler/tests.rs @@ -129,7 +129,7 @@ impl TestBuilder { cm.clone(), Loader { cm: cm.clone(), - files: self.files, + files: self.files.clone(), }, Default::default(), Config { @@ -141,6 +141,12 @@ impl TestBuilder { Box::new(Hook), ); + for (name, _) in self.files { + bundler + .load_transformed(&FileName::Real(name.clone().into())) + .unwrap(); + } + let mut t = Tester { cm: cm.clone(), bundler, diff --git a/bundler/tests/common/mod.rs b/bundler/tests/common/mod.rs index 590bf298f0b9..33c51c4bf1b6 100644 --- a/bundler/tests/common/mod.rs +++ b/bundler/tests/common/mod.rs @@ -7,6 +7,8 @@ use std::{ path::{Path, PathBuf}, }; use swc_bundler::{Load, ModuleData, Resolve}; +use swc_common::errors::ColorConfig; +use swc_common::errors::Handler; use swc_common::{comments::SingleThreadedComments, sync::Lrc, FileName, SourceMap}; use swc_ecma_parser::{lexer::Lexer, JscTarget, Parser, StringInput, Syntax, TsConfig}; use swc_ecma_transforms::{react, typescript::strip}; @@ -61,6 +63,8 @@ impl Load for Loader { } FileName::Custom(url) => { tsx = url.ends_with(".tsx"); + // Hack for jszip, which depends on invalid url. + let url = url.replace("https://deno.land/std@v", "https://deno.land/std@"); let url = Url::parse(&url).context("failed to parse url")?; @@ -85,7 +89,12 @@ impl Load for Loader { ); let mut parser = Parser::new_from(lexer); - let module = parser.parse_module().unwrap(); + let module = parser.parse_module().unwrap_or_else(|err| { + let handler = + Handler::with_tty_emitter(ColorConfig::Always, false, false, Some(self.cm.clone())); + err.into_diagnostic(&handler).emit(); + panic!("failed to parse") + }); let module = module .fold_with(&mut strip()) .fold_with(&mut react::react::( diff --git a/bundler/tests/deno-exec/deno-8224/.case2/entry.ts b/bundler/tests/deno-exec/deno-8224/.case2/entry.ts new file mode 100644 index 000000000000..3bc387d92ea1 --- /dev/null +++ b/bundler/tests/deno-exec/deno-8224/.case2/entry.ts @@ -0,0 +1 @@ +export * from 'https://dev.jspm.io/npm:@jspm/core@1.1.1/nodelibs/chunk-cffba9d4.js'; \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8224/all/entry.ts b/bundler/tests/deno-exec/deno-8224/all/entry.ts new file mode 100644 index 000000000000..9a093175e46c --- /dev/null +++ b/bundler/tests/deno-exec/deno-8224/all/entry.ts @@ -0,0 +1,20 @@ +import * as oak from 'https://deno.land/x/oak/mod.ts'; +import * as dsoReflect from 'https://deno.land/x/dso@v1.0.0/src/Reflect.ts'; +import * as path from 'https://deno.land/std/path/mod.ts'; +import * as uuid from 'https://deno.land/std/uuid/v4.ts'; +import * as fs from 'https://deno.land/std/fs/mod.ts'; +import * as flagTypes from 'https://deno.land/x/args@1.0.7/flag-types.ts'; +import * as valueTypes from 'https://deno.land/x/args@1.0.7/value-types.ts'; +import * as args from 'https://deno.land/x/args@1.0.7/wrapper.ts'; +import * as datetime from 'https://deno.land/std/datetime/mod.ts'; +import * as log from 'https://deno.land/std/log/mod.ts'; +import * as base64Url from 'https://deno.land/std/encoding/base64url.ts'; +import * as bytes from 'https://deno.land/std/bytes/mod.ts'; +import * as sha256 from 'https://deno.land/std/hash/sha256.ts'; +import * as jszip from 'https://deno.land/x/jszip/mod.ts'; +import * as signal from 'https://deno.land/std/signal/mod.ts'; + +console.log( + oak, dsoReflect, path, uuid, fs, flagTypes, valueTypes, + args, datetime, log, base64Url, bytes, sha256, jszip, signal +) \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8224/case1/entry.ts b/bundler/tests/deno-exec/deno-8224/case1/entry.ts new file mode 100644 index 000000000000..ecea7141ebe6 --- /dev/null +++ b/bundler/tests/deno-exec/deno-8224/case1/entry.ts @@ -0,0 +1,2 @@ +import * as nodelibs from 'https://dev.jspm.io/npm:@jspm/core@1.1.1/nodelibs/chunk-0c2d1322.js'; +console.log(nodelibs) \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8224/case3/entry.ts b/bundler/tests/deno-exec/deno-8224/case3/entry.ts new file mode 100644 index 000000000000..ae4aa640fa4b --- /dev/null +++ b/bundler/tests/deno-exec/deno-8224/case3/entry.ts @@ -0,0 +1 @@ +export * from 'https://dev.jspm.io/npm:@jspm/core@1.1.1/nodelibs/chunk-dac557ba.js'; \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8224/jszip/entry.ts b/bundler/tests/deno-exec/deno-8224/jszip/entry.ts new file mode 100644 index 000000000000..348c983fe45e --- /dev/null +++ b/bundler/tests/deno-exec/deno-8224/jszip/entry.ts @@ -0,0 +1,3 @@ +import * as jszip from 'https://deno.land/x/jszip/mod.ts'; + +console.log(jszip) \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8725/case5/deps.ts b/bundler/tests/deno-exec/deno-8725/case5/deps.ts new file mode 100644 index 000000000000..b2c7d84f9228 --- /dev/null +++ b/bundler/tests/deno-exec/deno-8725/case5/deps.ts @@ -0,0 +1 @@ +export * from 'https://raw.githubusercontent.com/nats-io/nats.ws/deno-1.6.0/src/mod.ts' \ No newline at end of file diff --git a/bundler/tests/deno-exec/deno-8725/case5/entry.ts b/bundler/tests/deno-exec/deno-8725/case5/entry.ts new file mode 100644 index 000000000000..235870ff1868 --- /dev/null +++ b/bundler/tests/deno-exec/deno-8725/case5/entry.ts @@ -0,0 +1,5 @@ +import { setUrlParseFn } from './deps'; + +if (!setUrlParseFn) { + throw new Error('bundle is invalid') +} \ No newline at end of file diff --git a/bundler/tests/deno-exec/.deno-8970/case1/entry.ts b/bundler/tests/deno-exec/deno-8970/case1/entry.ts similarity index 100% rename from bundler/tests/deno-exec/.deno-8970/case1/entry.ts rename to bundler/tests/deno-exec/deno-8970/case1/entry.ts diff --git a/bundler/tests/deno-exec/.deno-8970/case2/entry.ts b/bundler/tests/deno-exec/deno-8970/case2/entry.ts similarity index 100% rename from bundler/tests/deno-exec/.deno-8970/case2/entry.ts rename to bundler/tests/deno-exec/deno-8970/case2/entry.ts diff --git a/bundler/tests/fixture/circular-imports/complex-export/output/entry.js b/bundler/tests/fixture/circular-imports/complex-export/output/entry.js index b7cbaba5d661..5216d4dd69b9 100644 --- a/bundler/tests/fixture/circular-imports/complex-export/output/entry.js +++ b/bundler/tests/fixture/circular-imports/complex-export/output/entry.js @@ -1,6 +1,8 @@ -const c2 = 'c'; -const a2 = 'a'; -const a1 = a2; +const a = 'a'; +const c = 'c'; +const a1 = a; +const a2 = a1; export { a1 as a }; -const c1 = c2; +const c1 = c; +const c2 = c1; export { c1 as c }; diff --git a/bundler/tests/fixture/circular-imports/complex-import/output/entry.js b/bundler/tests/fixture/circular-imports/complex-import/output/entry.js index a8c9739643f5..7d2b4a8641b9 100644 --- a/bundler/tests/fixture/circular-imports/complex-import/output/entry.js +++ b/bundler/tests/fixture/circular-imports/complex-import/output/entry.js @@ -1,7 +1,7 @@ -const c = 'c'; const a = 'a'; const a1 = a; const a2 = a1; +const c = 'c'; const c1 = c; const c2 = c1; console.log(a2, c2); diff --git a/bundler/tests/fixture/circular-imports/simple/output/entry.js b/bundler/tests/fixture/circular-imports/simple/output/entry.js index f8a454b8d56b..97e6b2c32a66 100644 --- a/bundler/tests/fixture/circular-imports/simple/output/entry.js +++ b/bundler/tests/fixture/circular-imports/simple/output/entry.js @@ -1,7 +1,7 @@ -const b = 2; const a = 1; const a1 = a; const a2 = a1; +const b = 2; const b1 = b; const b2 = b1; console.log(a2, b2); diff --git a/bundler/tests/fixture/deno-8148/test-1/output/entry.ts b/bundler/tests/fixture/deno-8148/test-1/output/entry.ts index 7f092d89d335..36d5517a6792 100644 --- a/bundler/tests/fixture/deno-8148/test-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8148/test-1/output/entry.ts @@ -3,7 +3,7 @@ const mod = function() { } const A1 = A; return { - A + A: A1 }; }(); const foo = mod; diff --git a/bundler/tests/fixture/deno-8148/test-2/output/entry.ts b/bundler/tests/fixture/deno-8148/test-2/output/entry.ts index ed070700a4a7..2774c585e2a5 100644 --- a/bundler/tests/fixture/deno-8148/test-2/output/entry.ts +++ b/bundler/tests/fixture/deno-8148/test-2/output/entry.ts @@ -3,7 +3,7 @@ const mod = function() { } const foo1 = foo; return { - foo + foo: foo1 }; }(); const foo = mod; diff --git a/bundler/tests/fixture/deno-8148/test-3/output/entry.ts b/bundler/tests/fixture/deno-8148/test-3/output/entry.ts index 6e395ca8938e..3bda00686551 100644 --- a/bundler/tests/fixture/deno-8148/test-3/output/entry.ts +++ b/bundler/tests/fixture/deno-8148/test-3/output/entry.ts @@ -8,9 +8,9 @@ const mod = function() { const b1 = b; const c1 = c; return { - a, - b, - c + a: a1, + b: b1, + c: c1 }; }(); const foo = mod; diff --git a/bundler/tests/fixture/deno-8148/test-4/output/entry.ts b/bundler/tests/fixture/deno-8148/test-4/output/entry.ts index 78f95d293cf8..fc7d46fb12b2 100644 --- a/bundler/tests/fixture/deno-8148/test-4/output/entry.ts +++ b/bundler/tests/fixture/deno-8148/test-4/output/entry.ts @@ -3,12 +3,14 @@ const __default = { "b": "b", "c": "c" }; -const foo = __default; +const __default1 = __default; +const foo = __default1; console.log(foo); -const __default1 = { +const __default2 = { "a": "a1", "b": "b1", "c": "c1" }; -const foo1 = __default1; +const __default3 = __default2; +const foo1 = __default3; console.log(foo1); diff --git a/bundler/tests/fixture/deno-8188-1/output/entry.ts b/bundler/tests/fixture/deno-8188-1/output/entry.ts index eb1d595f32f6..3c70de7b735c 100644 --- a/bundler/tests/fixture/deno-8188-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8188-1/output/entry.ts @@ -2,12 +2,14 @@ const a = 1; const a1 = a; const a2 = a1; const a3 = a1; -const b = a3 + 1; -const c = a2 + 2; -const c1 = c; -const c2 = c1; -const a4 = a; +const a4 = a1; const a5 = a4; +const b = a2 + 1; const b1 = b; const b2 = b1; -console.log(a5, b2, c2); +const b3 = b2; +const c = a3 + 2; +const c1 = c; +const c2 = c1; +const c3 = c2; +console.log(a5, b3, c3); diff --git a/bundler/tests/fixture/deno-8188-2/output/entry.ts b/bundler/tests/fixture/deno-8188-2/output/entry.ts index 41e109bd8219..a7d733c69483 100644 --- a/bundler/tests/fixture/deno-8188-2/output/entry.ts +++ b/bundler/tests/fixture/deno-8188-2/output/entry.ts @@ -3,25 +3,26 @@ const a1 = a; const a2 = a1; const a3 = a1; const a4 = a1; -const b = a4 + 1; const a5 = a1; -const c = a5 + 2; -const user1 = a3 + 1; -const user11 = user1; -const user12 = user11; +const a6 = a1; +const a7 = a6; +const b = a4 + 1; const b1 = b; const b2 = b1; -console.log('user 1', user1); -const user2 = user12 + a2 + b2; -const user21 = user2; -const user22 = user21; -const user13 = user11; -console.log('user 2', user2); -const a6 = a; -const a7 = a6; -const b3 = b; +const b3 = b1; const b4 = b3; +const c = a5 + 2; const c1 = c; const c2 = c1; -console.log(a7, b4, c2); +const c3 = c2; +console.log(a7, b4, c3); +const user1 = a2 + 1; +console.log('user 1', user1); +const user11 = user1; +const user12 = user11; +const user13 = user11; +const user2 = user12 + a3 + b2; +console.log('user 2', user2); +const user21 = user2; +const user22 = user21; console.log(user13, user22); diff --git a/bundler/tests/fixture/deno-8188-3/output/entry.ts b/bundler/tests/fixture/deno-8188-3/output/entry.ts index 6094016d8de5..331011d50ce9 100644 --- a/bundler/tests/fixture/deno-8188-3/output/entry.ts +++ b/bundler/tests/fixture/deno-8188-3/output/entry.ts @@ -1,7 +1,8 @@ const a = 1; const a1 = a; const a2 = a1; -const a3 = a; -const b = a3; +const a3 = a2; +const b = a1; const b1 = b; -console.log(a2, b1); +const b2 = b1; +console.log(a3, b2); diff --git a/bundler/tests/fixture/deno-8211-1/output/entry.ts b/bundler/tests/fixture/deno-8211-1/output/entry.ts index 530dea5f4706..1a8d8a219115 100644 --- a/bundler/tests/fixture/deno-8211-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8211-1/output/entry.ts @@ -1,10 +1,14 @@ -class Zone3 { +class Zone { } -const __default = Zone3; -const Zone1 = __default; -class FixedOffsetZone2 extends Zone1 { +const __default = Zone; +const __default1 = __default; +const Zone1 = __default1; +const Zone2 = __default1; +const Zone3 = Zone2; +class FixedOffsetZone extends Zone1 { } -const Zone2 = __default; -const __default1 = FixedOffsetZone2; -const FixedOffsetZone1 = __default1; +const __default2 = FixedOffsetZone; +const __default3 = __default2; +const FixedOffsetZone1 = __default3; +const FixedOffsetZone2 = FixedOffsetZone1; export { Zone2 as Zone, FixedOffsetZone1 as FixedOffsetZone }; diff --git a/bundler/tests/fixture/deno-8211-2/output/entry.ts b/bundler/tests/fixture/deno-8211-2/output/entry.ts index c55de61d1d2f..452054d1f60e 100644 --- a/bundler/tests/fixture/deno-8211-2/output/entry.ts +++ b/bundler/tests/fixture/deno-8211-2/output/entry.ts @@ -1,18 +1,24 @@ -class Zone3 { +class Zone { } -const __default = Zone3; -const Zone1 = __default; -class FixedOffsetZone3 extends Zone1 { +const __default = Zone; +const __default1 = __default; +const Zone1 = __default1; +const Zone2 = __default1; +const Zone3 = Zone2; +class FixedOffsetZone extends Zone1 { } -const Zone2 = __default; -const __default1 = FixedOffsetZone3; -const FixedOffsetZone1 = __default1; -class Info2 { +const __default2 = FixedOffsetZone; +const __default3 = __default2; +const FixedOffsetZone1 = __default3; +const FixedOffsetZone2 = __default3; +const FixedOffsetZone3 = FixedOffsetZone2; +class Info { use() { console.log(FixedOffsetZone1); } } -const FixedOffsetZone2 = __default1; -const __default2 = Info2; -const Info1 = __default2; +const __default4 = Info; +const __default5 = __default4; +const Info1 = __default5; +const Info2 = Info1; export { Zone2 as Zone, Info1 as Info, FixedOffsetZone2 as FixedOffsetZone }; diff --git a/bundler/tests/fixture/deno-8302-1/output/entry.js b/bundler/tests/fixture/deno-8302-1/output/entry.js index e52bac702b54..041a0a5f858e 100644 --- a/bundler/tests/fixture/deno-8302-1/output/entry.js +++ b/bundler/tests/fixture/deno-8302-1/output/entry.js @@ -7,14 +7,14 @@ class A { const A1 = A; const A2 = A1; const A3 = A1; -console.log(a3, A3); +const A4 = A1; +console.log(a2, A2); const c = 3; const c1 = c; const c2 = c1; -const A4 = A1; -console.log(c2, A4); +console.log(c2, A3); const b = 2; const b1 = b; const b2 = b1; -console.log(b2, A2); -console.log(a2); +console.log(b2, A4); +console.log(a3); diff --git a/bundler/tests/fixture/deno-8325-1/output/entry.ts b/bundler/tests/fixture/deno-8325-1/output/entry.ts index 0c8abae8f2ce..57b2333bce2f 100644 --- a/bundler/tests/fixture/deno-8325-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8325-1/output/entry.ts @@ -1,3 +1,5 @@ -export default function square(a) { +function square(a) { return a * a; -}; +} +const __default = square; +export { __default as default }; diff --git a/bundler/tests/fixture/deno-8325-2/output/entry.ts b/bundler/tests/fixture/deno-8325-2/output/entry.ts index c1c346bd1dc4..d353e578a739 100644 --- a/bundler/tests/fixture/deno-8325-2/output/entry.ts +++ b/bundler/tests/fixture/deno-8325-2/output/entry.ts @@ -2,5 +2,6 @@ function square(a) { return a * a; } const __default = square; -const entry = __default; +const __default1 = __default; +const entry = __default1; console.log(entry()); diff --git a/bundler/tests/fixture/deno-8344-1/output/entry.ts b/bundler/tests/fixture/deno-8344-1/output/entry.ts index 25f7c3b52d20..d6ab1db417f0 100644 --- a/bundler/tests/fixture/deno-8344-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8344-1/output/entry.ts @@ -3,4 +3,5 @@ function u(str) { } const u1 = u; const u2 = u1; -console.log(u2("a")); +const u3 = u2; +console.log(u3("a")); diff --git a/bundler/tests/fixture/deno-8574/output/entry.ts b/bundler/tests/fixture/deno-8574/output/entry.ts index 75ab51564ddc..ddbbc0aa96f1 100644 --- a/bundler/tests/fixture/deno-8574/output/entry.ts +++ b/bundler/tests/fixture/deno-8574/output/entry.ts @@ -31,7 +31,7 @@ function mergeDeep(defaults, options) { const result = Object.assign({ }, defaults); Object.keys(options).forEach((key)=>{ - if (isPlainObject3(options[key])) { + if (isPlainObject2(options[key])) { if (!(key in defaults)) Object.assign(result, { [key]: options[key] }); @@ -322,12 +322,29 @@ function withDefaults(oldDefaults, newDefaults) { }); } const VERSION = "6.0.10"; -var queue = []; -var draining = false; function defaultSetTimout() { throw new Error("setTimeout has not been defined"); } +function defaultClearTimeout() { + throw new Error("clearTimeout has not been defined"); +} var cachedSetTimeout = defaultSetTimout; +var cachedClearTimeout = defaultClearTimeout; +var globalContext; +if (typeof window !== "undefined") { + globalContext = window; +} else if (typeof self !== "undefined") { + globalContext = self; +} else { + globalContext = { + }; +} +if (typeof globalContext.setTimeout === "function") { + cachedSetTimeout = setTimeout; +} +if (typeof globalContext.clearTimeout === "function") { + cachedClearTimeout = clearTimeout; +} function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { return setTimeout(fun, 0); @@ -346,12 +363,6 @@ function runTimeout(fun) { } } } -var currentQueue; -var queueIndex = -1; -function defaultClearTimeout() { - throw new Error("clearTimeout has not been defined"); -} -var cachedClearTimeout = defaultClearTimeout; function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { return clearTimeout(marker); @@ -370,6 +381,24 @@ function runClearTimeout(marker) { } } } +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} function drainQueue() { if (draining) { return; @@ -404,12 +433,24 @@ function nextTick(fun) { runTimeout(drainQueue); } } +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function() { + this.fun.apply(null, this.array); +}; var title = "browser"; +var platform = "browser"; var browser = true; var argv = []; var version = ""; var versions = { }; +var release = { +}; +var config = { +}; function noop() { } var on = noop; @@ -431,15 +472,6 @@ function chdir(dir) { function umask() { return 0; } -var globalContext; -if (typeof window !== "undefined") { - globalContext = window; -} else if (typeof self !== "undefined") { - globalContext = self; -} else { - globalContext = { - }; -} var performance = globalContext.performance || { }; var performanceNow = performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow || function() { @@ -462,11 +494,6 @@ function hrtime(previousTimestamp) { nanoseconds ]; } -var platform = "browser"; -var release = { -}; -var config = { -}; var startTime = new Date(); function uptime() { var currentTime = new Date(); @@ -511,20 +538,8 @@ function getUserAgent() { } const getUserAgent1 = getUserAgent; const getUserAgent2 = getUserAgent1; -var getGlobal = function() { - if (typeof self !== "undefined") { - return self; - } - if (typeof window !== "undefined") { - return window; - } - if (typeof global !== "undefined") { - return global; - } - throw new Error("unable to locate global object"); -}; const getUserAgent3 = getUserAgent1; -const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent3()}`; +const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent2()}`; const DEFAULTS = { method: "GET", baseUrl: "https://api.github.com", @@ -538,33 +553,26 @@ const DEFAULTS = { } }; const endpoint = withDefaults(null, DEFAULTS); -if (typeof globalContext.setTimeout === "function") { - cachedSetTimeout = setTimeout; -} -if (typeof globalContext.clearTimeout === "function") { - cachedClearTimeout = clearTimeout; -} -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; +const endpoint1 = endpoint; +const endpoint2 = endpoint1; +var getGlobal = function() { + if (typeof self !== "undefined") { + return self; } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; + if (typeof window !== "undefined") { + return window; } - if (queue.length) { - drainQueue(); + if (typeof global !== "undefined") { + return global; } -} -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function() { - this.fun.apply(null, this.array); + throw new Error("unable to locate global object"); }; +var global = getGlobal(); +var nodeFetch = global.fetch.bind(global); +const VERSION1 = "5.4.12"; +function getBufferResponse(response) { + return response.arrayBuffer(); +} class Deprecation extends Error { constructor(message){ super(message); @@ -574,6 +582,8 @@ class Deprecation extends Error { this.name = "Deprecation"; } } +const Deprecation1 = Deprecation; +const Deprecation2 = Deprecation1; var wrappy_1 = wrappy; function wrappy(fn, cb) { if (fn && cb) return wrappy(fn)(cb); @@ -598,7 +608,8 @@ function wrappy(fn, cb) { } } const __default = wrappy_1; -const wrappy2 = __default; +const __default1 = __default; +const wrappy2 = __default1; var once_1 = wrappy2(once2); var strict = wrappy2(onceStrict); once2.proto = once2(function() { @@ -636,12 +647,11 @@ function onceStrict(fn) { return f; } once_1.strict = strict; -const __default1 = once_1; -const once21 = __default1; +const __default2 = once_1; +const __default3 = __default2; +const once21 = __default3; const logOnce = once21((deprecation2)=>console.warn(deprecation2) ); -const Deprecation1 = Deprecation; -const Deprecation2 = Deprecation1; class RequestError extends Error { constructor(message1, statusCode, options){ super(message1); @@ -670,16 +680,10 @@ class RequestError extends Error { this.request = requestCopy; } } -var global = getGlobal(); -var nodeFetch = global.fetch.bind(global); const RequestError1 = RequestError; const RequestError2 = RequestError1; -const VERSION1 = "5.4.12"; -function getBufferResponse(response) { - return response.arrayBuffer(); -} function fetchWrapper(requestOptions) { - if (isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body)) { + if (isPlainObject3(requestOptions.body) || Array.isArray(requestOptions.body)) { requestOptions.body = JSON.stringify(requestOptions.body); } let headers = { @@ -778,16 +782,15 @@ function withDefaults1(oldEndpoint, newDefaults) { defaults: withDefaults1.bind(null, endpoint3) }); } -const endpoint1 = endpoint; -const endpoint2 = endpoint1; const request = withDefaults1(endpoint2, { headers: { - "user-agent": `octokit-request.js/${VERSION1} ${getUserAgent2()}` + "user-agent": `octokit-request.js/${VERSION1} ${getUserAgent3()}` } }); const request1 = request; const request2 = request1; -const { data } = await request2('GET /repos/{owner}/{repo}/license', { +const request3 = request2; +const { data } = await request3('GET /repos/{owner}/{repo}/license', { headers: { authorization: `token ${Deno.env.get('GITHUB_TOKEN')}` }, diff --git a/bundler/tests/fixture/deno-8584/output/entry.ts b/bundler/tests/fixture/deno-8584/output/entry.ts index 3403d1538d6f..f034c00abecf 100644 --- a/bundler/tests/fixture/deno-8584/output/entry.ts +++ b/bundler/tests/fixture/deno-8584/output/entry.ts @@ -4,7 +4,7 @@ const mod = await async function() { await setup(); const setup1 = setup; return { - setup + setup: setup1 }; }(); const log = mod; diff --git a/bundler/tests/fixture/deno-8625/output/entry.ts b/bundler/tests/fixture/deno-8625/output/entry.ts index ef280737ccfb..e573878c2231 100644 --- a/bundler/tests/fixture/deno-8625/output/entry.ts +++ b/bundler/tests/fixture/deno-8625/output/entry.ts @@ -6,10 +6,11 @@ const mod = function() { Foo }; }(); +const foo = mod; const Foo = mod.Foo; const Foo1 = Foo; const bar = Foo1('bar'); -const foo = mod; const __default = bar; -const bar1 = __default; +const __default1 = __default; +const bar1 = __default1; console.log(foo, bar1); diff --git a/bundler/tests/fixture/deno-8626-1/output/entry.ts b/bundler/tests/fixture/deno-8626-1/output/entry.ts index 55d78ee659d7..0b8dce18baec 100644 --- a/bundler/tests/fixture/deno-8626-1/output/entry.ts +++ b/bundler/tests/fixture/deno-8626-1/output/entry.ts @@ -1,8 +1,9 @@ const mod = function() { const foo = 'bar'; + const foo1 = foo; const bar = 123; return { - foo: foo, + foo: foo1, bar }; }(); diff --git a/bundler/tests/fixture/deno-8679/output/entry.ts b/bundler/tests/fixture/deno-8679/output/entry.ts index d305ba167f5d..02e1cce7dfe1 100644 --- a/bundler/tests/fixture/deno-8679/output/entry.ts +++ b/bundler/tests/fixture/deno-8679/output/entry.ts @@ -1,3 +1,5 @@ const __default = "one"; -const two = __default; +const __default1 = __default; +const __default2 = __default1; +const two = __default2; console.log(two); diff --git a/bundler/tests/fixture/deno-8680/output/entry.ts b/bundler/tests/fixture/deno-8680/output/entry.ts index 3f035c5617a3..6dad1e5ef10b 100644 --- a/bundler/tests/fixture/deno-8680/output/entry.ts +++ b/bundler/tests/fixture/deno-8680/output/entry.ts @@ -1,10 +1,11 @@ const mod = function() { const a = "hello world"; + const __instanceof = a; return { - instanceof: a + instanceof: __instanceof }; }(); +const y = mod; const __instanceof = mod.instanceof; const x = __instanceof; -const y = mod; console.log(x, y); diff --git a/bundler/tests/fixture/deno-8734/output/entry.ts b/bundler/tests/fixture/deno-8734/output/entry.ts index c53d9f37e343..08f9c0559b8c 100644 --- a/bundler/tests/fixture/deno-8734/output/entry.ts +++ b/bundler/tests/fixture/deno-8734/output/entry.ts @@ -1,18 +1,24 @@ -export class Comparator { +const m = "test"; +if (!m) { + throw new Error('b'); +} +class Comparator { constructor(comp1, optionsOrLoose = { }){ } parse(comp) { - const m = "another"; - if (!m) { + const m1 = "another"; + if (!m1) { throw new TypeError("Invalid comparator: " + comp); } - const m1 = m[1]; - console.log(m1); - if (!m[2]) { + const m11 = m1[1]; + console.log(m11); + if (!m1[2]) { console.log('other'); } } } const x = new Comparator('boo'); x.parse('test'); +const Comparator1 = Comparator; +export { Comparator as Comparator }; diff --git a/bundler/tests/fixture/deno-8978/input/deps.ts b/bundler/tests/fixture/deno-8978/input/deps.ts new file mode 100644 index 000000000000..27ba1c87c93c --- /dev/null +++ b/bundler/tests/fixture/deno-8978/input/deps.ts @@ -0,0 +1,3 @@ +export const f = () => "hello world"; +type f = number; +export const any = f; \ No newline at end of file diff --git a/bundler/tests/fixture/deno-8978/input/entry.ts b/bundler/tests/fixture/deno-8978/input/entry.ts new file mode 100644 index 000000000000..eded1fb142ee --- /dev/null +++ b/bundler/tests/fixture/deno-8978/input/entry.ts @@ -0,0 +1,4 @@ +import { any } from "./deps.ts"; + +export { any }; +export type { any as t }; \ No newline at end of file diff --git a/bundler/tests/fixture/deno-8978/output/entry.ts b/bundler/tests/fixture/deno-8978/output/entry.ts new file mode 100644 index 000000000000..1fdde8addb77 --- /dev/null +++ b/bundler/tests/fixture/deno-8978/output/entry.ts @@ -0,0 +1,7 @@ +const f = ()=>"hello world" +; +const any = f; +const any1 = any; +const any2 = any1; +const any3 = any2; +export { any2 as any }; diff --git a/bundler/tests/fixture/deno-9076/input/entry.ts b/bundler/tests/fixture/deno-9076/input/entry.ts new file mode 100644 index 000000000000..9822072d1b79 --- /dev/null +++ b/bundler/tests/fixture/deno-9076/input/entry.ts @@ -0,0 +1,7 @@ +class App { + constructor() { + console.log('Hello from app') + } +} + +const app = new App; \ No newline at end of file diff --git a/bundler/tests/fixture/deno-9076/output/entry.ts b/bundler/tests/fixture/deno-9076/output/entry.ts new file mode 100644 index 000000000000..4b0845dd6db3 --- /dev/null +++ b/bundler/tests/fixture/deno-9076/output/entry.ts @@ -0,0 +1,6 @@ +class App { + constructor(){ + console.log('Hello from app'); + } +} +const app = new App; diff --git a/bundler/tests/fixture/issue-1150-2/output/entry.ts b/bundler/tests/fixture/issue-1150-2/output/entry.ts index da64d866a70a..93afac87cf92 100644 --- a/bundler/tests/fixture/issue-1150-2/output/entry.ts +++ b/bundler/tests/fixture/issue-1150-2/output/entry.ts @@ -1,8 +1,3 @@ -function a() { - console.log("a"); -} -const a1 = a; -const a2 = a1; var O3; (function(O1) { O1[O1["A"] = 0] = "A"; @@ -10,6 +5,11 @@ var O3; O1[O1["C"] = 2] = "C"; })(O3 || (O3 = { })); +function a() { + console.log("a"); +} +const a1 = a; +const a2 = a1; const O1 = O3; const O2 = O1; export { O2 as O }; @@ -33,3 +33,4 @@ class A { let a4 = new A(); a4.a(); a4.c(); +const O4 = O2; diff --git a/bundler/tests/fixture/issue-1150/output/entry.ts b/bundler/tests/fixture/issue-1150/output/entry.ts index da64d866a70a..93afac87cf92 100644 --- a/bundler/tests/fixture/issue-1150/output/entry.ts +++ b/bundler/tests/fixture/issue-1150/output/entry.ts @@ -1,8 +1,3 @@ -function a() { - console.log("a"); -} -const a1 = a; -const a2 = a1; var O3; (function(O1) { O1[O1["A"] = 0] = "A"; @@ -10,6 +5,11 @@ var O3; O1[O1["C"] = 2] = "C"; })(O3 || (O3 = { })); +function a() { + console.log("a"); +} +const a1 = a; +const a2 = a1; const O1 = O3; const O2 = O1; export { O2 as O }; @@ -33,3 +33,4 @@ class A { let a4 = new A(); a4.a(); a4.c(); +const O4 = O2; diff --git a/bundler/tests/fixture/issue-1155-1-fn/output/entry.ts b/bundler/tests/fixture/issue-1155-1-fn/output/entry.ts index 8ed9e0c7766c..8252534cf2d3 100644 --- a/bundler/tests/fixture/issue-1155-1-fn/output/entry.ts +++ b/bundler/tests/fixture/issue-1155-1-fn/output/entry.ts @@ -3,7 +3,8 @@ function a() { } const a1 = a; const a2 = a1; +const a3 = a2; function b() { - a2(); + a3(); } b(); diff --git a/bundler/tests/fixture/issue-1155-2-var/output/entry.ts b/bundler/tests/fixture/issue-1155-2-var/output/entry.ts index cfc1bce59437..5ed158f7a415 100644 --- a/bundler/tests/fixture/issue-1155-2-var/output/entry.ts +++ b/bundler/tests/fixture/issue-1155-2-var/output/entry.ts @@ -1,7 +1,8 @@ const a = 'a'; const a1 = a; const a2 = a1; +const a3 = a2; function b() { - return a2; + return a3; } b(); diff --git a/bundler/tests/fixture/issue-1155-3-class/output/entry.ts b/bundler/tests/fixture/issue-1155-3-class/output/entry.ts index 0fd4712c3ee0..42da7ba9d9e3 100644 --- a/bundler/tests/fixture/issue-1155-3-class/output/entry.ts +++ b/bundler/tests/fixture/issue-1155-3-class/output/entry.ts @@ -2,7 +2,8 @@ class a { } const a1 = a; const a2 = a1; +const a3 = a2; function b() { - return new a2(); + return new a3(); } b(); diff --git a/bundler/tests/fixture/reexport/idnex-style/output/entry.ts b/bundler/tests/fixture/reexport/idnex-style/output/entry.ts index 21d3dce81633..8bbbd42c0b21 100644 --- a/bundler/tests/fixture/reexport/idnex-style/output/entry.ts +++ b/bundler/tests/fixture/reexport/idnex-style/output/entry.ts @@ -2,4 +2,5 @@ class A { } const A1 = A; const A2 = A1; -console.log(A2); +const A3 = A2; +console.log(A3); diff --git a/bundler/tests/fixture/reexport/nested/output/entry.js b/bundler/tests/fixture/reexport/nested/output/entry.js index 8e7fd32b7dbf..f500630cdfb3 100644 --- a/bundler/tests/fixture/reexport/nested/output/entry.js +++ b/bundler/tests/fixture/reexport/nested/output/entry.js @@ -1,5 +1,11 @@ -export const a = 1; -export function foo() { +const a = 1; +function foo() { } -export class Class { +class Class { } +const a1 = a; +const foo1 = foo; +const Class1 = Class; +export { a as a }; +export { foo as foo }; +export { Class as Class }; diff --git a/bundler/tests/fixture/sort/enum-reexport/output/entry.ts b/bundler/tests/fixture/sort/enum-reexport/output/entry.ts index 0ec258080ae6..e9ae3e0bda65 100644 --- a/bundler/tests/fixture/sort/enum-reexport/output/entry.ts +++ b/bundler/tests/fixture/sort/enum-reexport/output/entry.ts @@ -1,7 +1,9 @@ -var Status2; +var Status; (function(Status1) { Status1[Status1["Continue"] = 100] = "Continue"; -})(Status2 || (Status2 = { +})(Status || (Status = { })); -const Status1 = Status2; -export { Status1 as Status }; +const Status1 = Status; +const Status2 = Status1; +const Status3 = Status2; +export { Status2 as Status }; diff --git a/bundler/tests/fixture/wrapped/export-named/output/entry.ts b/bundler/tests/fixture/wrapped/export-named/output/entry.ts index 172a5c124a4d..ae55a128b1c1 100644 --- a/bundler/tests/fixture/wrapped/export-named/output/entry.ts +++ b/bundler/tests/fixture/wrapped/export-named/output/entry.ts @@ -5,8 +5,9 @@ const [a, b, c] = [ ]; const b1 = b; const mod = function() { + const b2 = b1; return { - b: b1 + b: b2 }; }(); const foo = mod; diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index daa7003631ef..69328f0a3658 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecmascript" repository = "https://github.com/swc-project/swc.git" -version = "0.17.0" +version = "0.17.1" [features] codegen = ["swc_ecma_codegen"] @@ -28,7 +28,7 @@ swc_ecma_ast = {version = "0.36.0", path = "./ast"} swc_ecma_codegen = {version = "0.42.0", path = "./codegen", optional = true} swc_ecma_dep_graph = {version = "0.11.0", path = "./dep-graph", optional = true} swc_ecma_parser = {version = "0.44.0", path = "./parser", optional = true} -swc_ecma_transforms = {version = "0.32.0", path = "./transforms", optional = true} +swc_ecma_transforms = {version = "0.32.1", path = "./transforms", optional = true} swc_ecma_utils = {version = "0.26.0", path = "./utils", optional = true} swc_ecma_visit = {version = "0.22.0", path = "./visit", optional = true} diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml index 6c3d81619779..9cdabeff09c9 100644 --- a/ecmascript/transforms/Cargo.toml +++ b/ecmascript/transforms/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms" repository = "https://github.com/swc-project/swc.git" -version = "0.32.0" +version = "0.32.1" [features] compat = ["swc_ecma_transforms_compat"] @@ -24,10 +24,10 @@ swc_ecma_parser = {version = "0.44.0", path = "../parser"} swc_ecma_transforms_base = {version = "0.1.0", path = "./base"} swc_ecma_transforms_compat = {version = "0.2.0", path = "./compat", optional = true} swc_ecma_transforms_module = {version = "0.2.0", path = "./module", optional = true} -swc_ecma_transforms_optimization = {version = "0.2.0", path = "./optimization", optional = true} +swc_ecma_transforms_optimization = {version = "0.2.2", path = "./optimization", optional = true} swc_ecma_transforms_proposal = {version = "0.2.0", path = "./proposal", optional = true} swc_ecma_transforms_react = {version = "0.2.0", path = "./react", optional = true} -swc_ecma_transforms_typescript = {version = "0.2.0", path = "./typescript", optional = true} +swc_ecma_transforms_typescript = {version = "0.2.1", path = "./typescript", optional = true} swc_ecma_utils = {version = "0.26.0", path = "../utils"} swc_ecma_visit = {version = "0.22.0", path = "../visit"} unicode-xid = "0.2" diff --git a/ecmascript/transforms/optimization/Cargo.toml b/ecmascript/transforms/optimization/Cargo.toml index 1187b26185cc..a160c197110b 100644 --- a/ecmascript/transforms/optimization/Cargo.toml +++ b/ecmascript/transforms/optimization/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_optimization" repository = "https://github.com/swc-project/swc.git" -version = "0.2.1" +version = "0.2.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/ecmascript/transforms/optimization/src/simplify/dce/mod.rs b/ecmascript/transforms/optimization/src/simplify/dce/mod.rs index 1720b6970881..27abe7b0d559 100644 --- a/ecmascript/transforms/optimization/src/simplify/dce/mod.rs +++ b/ecmascript/transforms/optimization/src/simplify/dce/mod.rs @@ -577,6 +577,10 @@ impl VisitMut for Dce<'_> { } d.visit_mut_children_with(self); + + if self.is_marked(d.name.span()) || self.is_marked(d.init.span()) { + d.span = d.span.apply_mark(self.config.used_mark); + } } fn visit_mut_var_decl(&mut self, mut var: &mut VarDecl) { @@ -663,21 +667,10 @@ impl VisitMut for Dce<'_> { return; } - node.visit_mut_children_with(self); - - if self.marking_phase - || self.is_marked(node.callee.span()) - || node - .args - .as_ref() - .map(|args| args.iter().any(|arg| self.is_marked(arg.expr.span()))) - .unwrap_or(false) - { - node.span = node.span.apply_mark(self.config.used_mark); + node.span = node.span.apply_mark(self.config.used_mark); - self.mark(&mut node.callee); - self.mark(&mut node.args); - } + self.mark(&mut node.callee); + self.mark(&mut node.args); } fn visit_mut_call_expr(&mut self, node: &mut CallExpr) { diff --git a/ecmascript/transforms/optimization/tests/simplify_dce.rs b/ecmascript/transforms/optimization/tests/simplify_dce.rs index 27b48d1a59e5..f3d337644784 100644 --- a/ecmascript/transforms/optimization/tests/simplify_dce.rs +++ b/ecmascript/transforms/optimization/tests/simplify_dce.rs @@ -834,3 +834,18 @@ noop!( console.log(`Test is ${TEST}`); " ); + +noop!( + deno_9076, + " + class App + { + constructor() + { + console.log('Hello from app') + } + } + + const app = new App; + " +); diff --git a/ecmascript/transforms/typescript/Cargo.toml b/ecmascript/transforms/typescript/Cargo.toml index c1c940320757..a7a599d48db0 100644 --- a/ecmascript/transforms/typescript/Cargo.toml +++ b/ecmascript/transforms/typescript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_typescript" repository = "https://github.com/swc-project/swc.git" -version = "0.2.0" +version = "0.2.1" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/ecmascript/transforms/typescript/src/strip.rs b/ecmascript/transforms/typescript/src/strip.rs index d1a0090e1c42..8b2a6dfe7f74 100644 --- a/ecmascript/transforms/typescript/src/strip.rs +++ b/ecmascript/transforms/typescript/src/strip.rs @@ -509,7 +509,7 @@ impl Visit for Strip { self.scope .imported_idents .entry((n.sym.clone(), n.span.ctxt())) - .and_modify(|v| v.has_concrete = !is_type_only_export); + .and_modify(|v| v.has_concrete |= !is_type_only_export); n.visit_children_with(self); } diff --git a/ecmascript/transforms/typescript/tests/strip.rs b/ecmascript/transforms/typescript/tests/strip.rs index e7e7532c45f9..e40ad5de4e13 100644 --- a/ecmascript/transforms/typescript/tests/strip.rs +++ b/ecmascript/transforms/typescript/tests/strip.rs @@ -3294,3 +3294,18 @@ let A = _decorate([], function(_initialize) { }); " ); + +to!( + deno_8978, + " + import { any } from './dep.ts'; + + export { any }; + export type { any as t }; + ", + " + import { any } from './dep.ts'; + + export { any }; + " +); diff --git a/spack/tests/pass/alias/export-default/output/entry.js b/spack/tests/pass/alias/export-default/output/entry.js index c70416d3421d..f1ac2e03cac4 100644 --- a/spack/tests/pass/alias/export-default/output/entry.js +++ b/spack/tests/pass/alias/export-default/output/entry.js @@ -1,4 +1,5 @@ const foo = 1; const __default = foo; -const a = __default; +const __default1 = __default; +const a = __default1; console.log(a); diff --git a/spack/tests/pass/alias/import/multi/output/entry.js b/spack/tests/pass/alias/import/multi/output/entry.js index 16e0b60f38c1..4d072210505f 100644 --- a/spack/tests/pass/alias/import/multi/output/entry.js +++ b/spack/tests/pass/alias/import/multi/output/entry.js @@ -1,15 +1,15 @@ function a() { - console.log("a()"); } function b() { - console.log("a()"); } function a1() { + console.log("a()"); } +const a2 = a1; +const foo = a2; function b1() { + console.log("a()"); } -const a2 = a; -const foo = a2; -const b2 = b; +const b2 = b1; const bar = b2; -console.log(a1(), foo(), b1(), bar()); +console.log(a(), foo(), b(), bar()); diff --git a/spack/tests/pass/alias/import/simple/output/entry.js b/spack/tests/pass/alias/import/simple/output/entry.js index 92544293ee11..3cfd319f9a50 100644 --- a/spack/tests/pass/alias/import/simple/output/entry.js +++ b/spack/tests/pass/alias/import/simple/output/entry.js @@ -1,8 +1,8 @@ function a() { - console.log("a()"); } function a1() { + console.log("a()"); } -const a2 = a; +const a2 = a1; const foo = a2; -console.log(a1(), foo()); +console.log(a(), foo()); diff --git a/spack/tests/pass/basic/extends/output/entry.js b/spack/tests/pass/basic/extends/output/entry.js index 63f3111243d0..e227ee834bd3 100644 --- a/spack/tests/pass/basic/extends/output/entry.js +++ b/spack/tests/pass/basic/extends/output/entry.js @@ -2,9 +2,9 @@ class B { } const B1 = B; const B2 = B1; +const B3 = B1; class A extends B2 { } -const B3 = B1; const A1 = A; const A2 = A1; console.log(A2, B3); diff --git a/spack/tests/pass/circular/complex-class-function/output/entry.js b/spack/tests/pass/circular/complex-class-function/output/entry.js index b14c8db0df9e..bd87fec7c499 100644 --- a/spack/tests/pass/circular/complex-class-function/output/entry.js +++ b/spack/tests/pass/circular/complex-class-function/output/entry.js @@ -1,11 +1,11 @@ +function a() { + return new A(); +} function getC() { return C; } class C { } -function a() { - return new A(); -} const getC1 = getC; const getC2 = getC1; class A extends getC2() { diff --git a/spack/tests/pass/circular/hygiene/class-inheritance/output/entry.js b/spack/tests/pass/circular/hygiene/class-inheritance/output/entry.js index 33c2ff7f905f..548f977eb8b3 100644 --- a/spack/tests/pass/circular/hygiene/class-inheritance/output/entry.js +++ b/spack/tests/pass/circular/hygiene/class-inheritance/output/entry.js @@ -3,22 +3,22 @@ class C { throw new Error('Unimplemented'); } b() { - return new B3(); + return new B2(); } } const C1 = C; const C2 = C1; class B extends C2 { a() { - return new A3(); + return new A2(); } } const B1 = B; const B2 = B1; -class A extends B2 { -} const B3 = B1; +class A extends B3 { +} const A1 = A; const A2 = A1; -console.log(A2, 'Loaded!'); const A3 = A1; +console.log(A3, 'Loaded!'); diff --git a/spack/tests/pass/circular/imports-same/output/entry.js b/spack/tests/pass/circular/imports-same/output/entry.js index d63794fbb003..3c7ae993c006 100644 --- a/spack/tests/pass/circular/imports-same/output/entry.js +++ b/spack/tests/pass/circular/imports-same/output/entry.js @@ -3,4 +3,6 @@ const foo1 = foo; const foo2 = foo1; const foo3 = foo2; console.log('a', foo3); -export const a = foo3 + 1; +const a = foo3 + 1; +const a1 = a; +export { a as a }; diff --git a/spack/tests/pass/circular/mixed/output/entry.js b/spack/tests/pass/circular/mixed/output/entry.js index 87cad993ac27..1933dafd21c2 100644 --- a/spack/tests/pass/circular/mixed/output/entry.js +++ b/spack/tests/pass/circular/mixed/output/entry.js @@ -1,15 +1,15 @@ -console.log('c'); class A { method() { - return new B3(); + return new B2(); } } const A1 = A; const A2 = A1; const A3 = A1; -class B extends A3 { +class B extends A2 { } const B1 = B; const B2 = B1; -console.log(A2, B2); const B3 = B1; +console.log(A3, B3); +console.log('c'); diff --git a/spack/tests/pass/circular/simple/output/entry.js b/spack/tests/pass/circular/simple/output/entry.js index a0794c2769b2..c9a5c116b91d 100644 --- a/spack/tests/pass/circular/simple/output/entry.js +++ b/spack/tests/pass/circular/simple/output/entry.js @@ -1,14 +1,14 @@ class A { method() { - return new B3(); + return new B2(); } } const A1 = A; const A2 = A1; const A3 = A1; -class B extends A3 { +class B extends A2 { } const B1 = B; const B2 = B1; -console.log(A2, B2); const B3 = B1; +console.log(A3, B3); diff --git a/spack/tests/pass/circular/top-level-idents/output/entry.js b/spack/tests/pass/circular/top-level-idents/output/entry.js index 291bdc4563aa..6f095f39ec06 100644 --- a/spack/tests/pass/circular/top-level-idents/output/entry.js +++ b/spack/tests/pass/circular/top-level-idents/output/entry.js @@ -1,4 +1,4 @@ -console.log('c'); -console.log('b'); -console.log('a'); console.log('entry'); +console.log('a'); +console.log('b'); +console.log('c'); diff --git a/spack/tests/pass/cjs/common-library/output/entry.js b/spack/tests/pass/cjs/common-library/output/entry.js index fe9b2178d108..89cb8d8c3725 100644 --- a/spack/tests/pass/cjs/common-library/output/entry.js +++ b/spack/tests/pass/cjs/common-library/output/entry.js @@ -19,16 +19,14 @@ var load = __spack_require__.bind(void 0, function(module, exports) { }); var load1 = __spack_require__.bind(void 0, function(module, exports) { const Common = load(); - module.exports = class B extends Common { + module.exports = class A extends Common { }; - const B1 = module.exports; }); +var { default: A } = load1(); var load2 = __spack_require__.bind(void 0, function(module, exports) { const Common = load(); - module.exports = class A extends Common { + module.exports = class B extends Common { }; - const A1 = module.exports; }); -var { default: A } = load2(); -var { default: B } = load1(); +var { default: B } = load2(); console.log(A, B); diff --git a/spack/tests/pass/cjs/mixed/output/entry.js b/spack/tests/pass/cjs/mixed/output/entry.js index 8558267207ca..888d5c759d88 100644 --- a/spack/tests/pass/cjs/mixed/output/entry.js +++ b/spack/tests/pass/cjs/mixed/output/entry.js @@ -18,7 +18,6 @@ var load = __spack_require__.bind(void 0, function(module, exports) { module1.exports = 1; }); module.exports = load1(); - const a = module.exports; }); var { default: a } = load(); console.log(a); diff --git a/spack/tests/pass/deno-001/full/output/entry.js b/spack/tests/pass/deno-001/full/output/entry.js index f51e297637c6..c020cd513285 100644 --- a/spack/tests/pass/deno-001/full/output/entry.js +++ b/spack/tests/pass/deno-001/full/output/entry.js @@ -1,21 +1,179 @@ -const DEFAULT_BUF_SIZE = 4096; -const MIN_BUF_SIZE = 16; -const MAX_CONSECUTIVE_EMPTY_READS = 100; -const CR = "\r".charCodeAt(0); -const LF = "\n".charCodeAt(0); -class BufferFullError extends Error { - constructor(partial){ - super("Buffer full"); - this.partial = partial; - this.name = "BufferFullError"; +function emptyReader() { + return { + read (_) { + return Promise.resolve(null); + } + }; +} +function bodyReader(contentLength, r) { + let totalRead = 0; + let finished = false; + async function read(buf) { + if (finished) return null; + let result; + const remaining = contentLength - totalRead; + if (remaining >= buf.byteLength) result = await r.read(buf); + else { + const readBuf = buf.subarray(0, remaining); + result = await r.read(readBuf); + } + if (result !== null) totalRead += result; + finished = totalRead === contentLength; + return result; } + return { + read + }; } -class PartialReadError extends Deno.errors.UnexpectedEof { - constructor(){ - super("Encountered UnexpectedEof, data only partially read"); - this.name = "PartialReadError"; +function findIndex(source, pat) { + const s = pat[0]; + for(let i = 0; i < source.length; i++){ + if (source[i] !== s) continue; + const pin = i; + let matched = 1; + let j = i; + while(matched < pat.length){ + j++; + if (source[j] !== pat[j - pin]) break; + matched++; + } + if (matched === pat.length) return pin; + } + return -1; +} +function concat(origin, b) { + const output = new Uint8Array(origin.length + b.length); + output.set(origin, 0); + output.set(b, origin.length); + return output; +} +function copyBytes(src, dst, off = 0) { + off = Math.max(0, Math.min(off, dst.byteLength)); + const dstBytesAvailable = dst.byteLength - off; + if (src.byteLength > dstBytesAvailable) src = src.subarray(0, dstBytesAvailable); + dst.set(src, off); + return src.byteLength; +} +const concat1 = concat; +const concat2 = concat1; +// FROM https://github.com/denoland/deno/blob/b34628a26ab0187a827aa4ebe256e23178e25d39/cli/js/web/headers.ts#L9 +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/g; +const encoder = new TextEncoder(); +function encode(input) { + return encoder.encode(input); +} +const decoder = new TextDecoder(); +function decode(input) { + return decoder.decode(input); +} +const decode1 = decode; +const decode2 = decode1; +function str(buf) { + if (buf == null) return ""; + else return decode2(buf); +} +function charCode(s) { + return s.charCodeAt(0); +} +class TextProtoReader { + /** readLine() reads a single line from the TextProtoReader, + * eliding the final \n or \r\n from the returned string. + */ async readLine() { + const s = await this.readLineSlice(); + if (s === null) return null; + return str(s); + } + /** ReadMIMEHeader reads a MIME-style header from r. + * The header is a sequence of possibly continued Key: Value lines + * ending in a blank line. + * The returned map m maps CanonicalMIMEHeaderKey(key) to a + * sequence of values in the same order encountered in the input. + * + * For example, consider this input: + * + * My-Key: Value 1 + * Long-Key: Even + * Longer Value + * My-Key: Value 2 + * + * Given that input, ReadMIMEHeader returns the map: + * + * map[string][]string{ + * "My-Key": {"Value 1", "Value 2"}, + * "Long-Key": {"Even Longer Value"}, + * } + */ async readMIMEHeader() { + const m = new Headers(); + let line; + // The first line cannot start with a leading space. + let buf = await this.r.peek(1); + if (buf === null) return null; + else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) line = await this.readLineSlice(); + buf = await this.r.peek(1); + if (buf === null) throw new Deno.errors.UnexpectedEof(); + else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) throw new Deno.errors.InvalidData(`malformed MIME header initial line: ${str(line)}`); + while(true){ + const kv = await this.readLineSlice(); // readContinuedLineSlice + if (kv === null) throw new Deno.errors.UnexpectedEof(); + if (kv.byteLength === 0) return m; + // Key ends at first colon + let i = kv.indexOf(charCode(":")); + if (i < 0) throw new Deno.errors.InvalidData(`malformed MIME header line: ${str(kv)}`); + //let key = canonicalMIMEHeaderKey(kv.subarray(0, endKey)); + const key = str(kv.subarray(0, i)); + // As per RFC 7230 field-name is a token, + // tokens consist of one or more chars. + // We could throw `Deno.errors.InvalidData` here, + // but better to be liberal in what we + // accept, so if we get an empty key, skip it. + if (key == "") continue; + // Skip initial spaces in value. + i++; // skip colon + while(i < kv.byteLength && (kv[i] == charCode(" ") || kv[i] == charCode("\t")))i++; + const value = str(kv.subarray(i)).replace(invalidHeaderCharRegex, encodeURI); + // In case of invalid header we swallow the error + // example: "Audio Mode" => invalid due to space in the key + try { + m.append(key, value); + } catch { + } + } + } + async readLineSlice() { + // this.closeDot(); + let line; + while(true){ + const r = await this.r.readLine(); + if (r === null) return null; + const { line: l , more } = r; + // Avoid the copy if the first call produced a full line. + if (!line && !more) { + // TODO(ry): + // This skipSpace() is definitely misplaced, but I don't know where it + // comes from nor how to fix it. + if (this.skipSpace(l) === 0) return new Uint8Array(0); + return l; + } + line = line ? concat2(line, l) : l; + if (!more) break; + } + return line; + } + skipSpace(l) { + let n = 0; + for(let i = 0; i < l.length; i++){ + if (l[i] === charCode(" ") || l[i] === charCode("\t")) continue; + n++; + } + return n; + } + constructor(r1){ + this.r = r1; + this.r = r1; } } +const TextProtoReader1 = TextProtoReader; +const TextProtoReader2 = TextProtoReader1; class DenoStdInternalError extends Error { constructor(message){ super(message); @@ -28,15 +186,128 @@ function assert(expr, msg = "") { const assert1 = assert; const assert2 = assert1; const assert3 = assert1; -function copyBytes(src, dst, off = 0) { - off = Math.max(0, Math.min(off, dst.byteLength)); - const dstBytesAvailable = dst.byteLength - off; - if (src.byteLength > dstBytesAvailable) src = src.subarray(0, dstBytesAvailable); - dst.set(src, off); - return src.byteLength; +const assert4 = assert1; +function chunkedBodyReader(h, r1) { + // Based on https://tools.ietf.org/html/rfc2616#section-19.4.6 + const tp = new TextProtoReader2(r1); + let finished = false; + const chunks = []; + async function read(buf) { + if (finished) return null; + const [chunk] = chunks; + if (chunk) { + const chunkRemaining = chunk.data.byteLength - chunk.offset; + const readLength = Math.min(chunkRemaining, buf.byteLength); + for(let i = 0; i < readLength; i++)buf[i] = chunk.data[chunk.offset + i]; + chunk.offset += readLength; + if (chunk.offset === chunk.data.byteLength) { + chunks.shift(); + // Consume \r\n; + if (await tp.readLine() === null) throw new Deno.errors.UnexpectedEof(); + } + return readLength; + } + const line = await tp.readLine(); + if (line === null) throw new Deno.errors.UnexpectedEof(); + // TODO: handle chunk extension + const [chunkSizeString] = line.split(";"); + const chunkSize = parseInt(chunkSizeString, 16); + if (Number.isNaN(chunkSize) || chunkSize < 0) throw new Error("Invalid chunk size"); + if (chunkSize > 0) { + if (chunkSize > buf.byteLength) { + let eof = await r1.readFull(buf); + if (eof === null) throw new Deno.errors.UnexpectedEof(); + const restChunk = new Uint8Array(chunkSize - buf.byteLength); + eof = await r1.readFull(restChunk); + if (eof === null) throw new Deno.errors.UnexpectedEof(); + else chunks.push({ + offset: 0, + data: restChunk + }); + return buf.byteLength; + } else { + const bufToFill = buf.subarray(0, chunkSize); + const eof = await r1.readFull(bufToFill); + if (eof === null) throw new Deno.errors.UnexpectedEof(); + // Consume \r\n + if (await tp.readLine() === null) throw new Deno.errors.UnexpectedEof(); + return chunkSize; + } + } else { + assert3(chunkSize === 0); + // Consume \r\n + if (await r1.readLine() === null) throw new Deno.errors.UnexpectedEof(); + await readTrailers(h, r1); + finished = true; + return null; + } + } + return { + read + }; +} +function isProhibidedForTrailer(key) { + const s = new Set([ + "transfer-encoding", + "content-length", + "trailer" + ]); + return s.has(key.toLowerCase()); +} +async function readTrailers(headers, r1) { + const trailers = parseTrailer(headers.get("trailer")); + if (trailers == null) return; + const trailerNames = [ + ...trailers.keys() + ]; + const tp = new TextProtoReader2(r1); + const result = await tp.readMIMEHeader(); + if (result == null) throw new Deno.errors.InvalidData("Missing trailer header."); + const undeclared = [ + ...result.keys() + ].filter((k)=>!trailerNames.includes(k) + ); + if (undeclared.length > 0) throw new Deno.errors.InvalidData(`Undeclared trailers: ${Deno.inspect(undeclared)}.`); + for (const [k, v] of result)headers.append(k, v); + const missingTrailers = trailerNames.filter((k1)=>!result.has(k1) + ); + if (missingTrailers.length > 0) throw new Deno.errors.InvalidData(`Missing trailers: ${Deno.inspect(missingTrailers)}.`); + headers.delete("trailer"); +} +function parseTrailer(field) { + if (field == null) return undefined; + const trailerNames = field.split(",").map((v)=>v.trim().toLowerCase() + ); + if (trailerNames.length === 0) throw new Deno.errors.InvalidData("Empty trailer header."); + const prohibited = trailerNames.filter((k)=>isProhibidedForTrailer(k) + ); + if (prohibited.length > 0) throw new Deno.errors.InvalidData(`Prohibited trailer names: ${Deno.inspect(prohibited)}.`); + return new Headers(trailerNames.map((key)=>[ + key, + "" + ] + )); } const copyBytes1 = copyBytes; const copyBytes2 = copyBytes1; +const DEFAULT_BUF_SIZE = 4096; +const MIN_BUF_SIZE = 16; +const MAX_CONSECUTIVE_EMPTY_READS = 100; +const CR = "\r".charCodeAt(0); +const LF = "\n".charCodeAt(0); +class BufferFullError extends Error { + constructor(partial){ + super("Buffer full"); + this.partial = partial; + this.name = "BufferFullError"; + } +} +class PartialReadError extends Deno.errors.UnexpectedEof { + constructor(){ + super("Encountered UnexpectedEof, data only partially read"); + this.name = "PartialReadError"; + } +} class BufReader { // private lastByte: number; // private lastCharSize: number; @@ -65,7 +336,7 @@ class BufReader { this.eof = true; return; } - assert3(rr >= 0, "negative read"); + assert2(rr >= 0, "negative read"); this.w += rr; if (rr > 0) return; } @@ -95,7 +366,7 @@ class BufReader { // Read directly into p to avoid copy. const rr1 = await this.rd.read(p); const nread = rr1 ?? 0; - assert3(nread >= 0, "negative read"); + assert2(nread >= 0, "negative read"); // if (rr.nread > 0) { // this.lastByte = p[rr.nread - 1]; // this.lastCharSize = -1; @@ -108,7 +379,7 @@ class BufReader { this.w = 0; rr = await this.rd.read(this.buf); if (rr === 0 || rr === null) return rr; - assert3(rr >= 0, "negative read"); + assert2(rr >= 0, "negative read"); this.w += rr; } // copy as much as we can @@ -197,7 +468,7 @@ class BufReader { line = await this.readSlice(LF); } catch (err) { let { partial: partial1 } = err; - assert3(partial1 instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property"); + assert2(partial1 instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property"); // Don't throw if `readSlice()` failed with `BufferFullError`, instead we // just return whatever is available and set the `more` flag. if (!(err instanceof BufferFullError)) throw err; @@ -205,7 +476,7 @@ class BufReader { if (!this.eof && partial1.byteLength > 0 && partial1[partial1.byteLength - 1] === CR) { // Put the '\r' back on buf and drop it from line. // Let the next call to ReadLine check for "\r\n". - assert3(this.r > 0, "bufio: tried to rewind past start of buffer"); + assert2(this.r > 0, "bufio: tried to rewind past start of buffer"); this.r--; partial1 = partial1.subarray(0, partial1.byteLength - 1); } @@ -447,378 +718,96 @@ class BufWriterSync extends AbstractBufBase { this.err = e; throw e; } - else { - numBytesWritten = copyBytes2(data, this.buf, this.usedBufferBytes); - this.usedBufferBytes += numBytesWritten; - this.flush(); - } - totalBytesWritten += numBytesWritten; - data = data.subarray(numBytesWritten); - } - numBytesWritten = copyBytes2(data, this.buf, this.usedBufferBytes); - this.usedBufferBytes += numBytesWritten; - totalBytesWritten += numBytesWritten; - return totalBytesWritten; - } - constructor(writer2, size3 = DEFAULT_BUF_SIZE){ - super(); - this.writer = writer2; - if (size3 <= 0) size3 = DEFAULT_BUF_SIZE; - this.buf = new Uint8Array(size3); - } -} -/** Generate longest proper prefix which is also suffix array. */ function createLPS(pat) { - const lps = new Uint8Array(pat.length); - lps[0] = 0; - let prefixEnd = 0; - let i = 1; - while(i < lps.length)if (pat[i] == pat[prefixEnd]) { - prefixEnd++; - lps[i] = prefixEnd; - i++; - } else if (prefixEnd === 0) { - lps[i] = 0; - i++; - } else prefixEnd = pat[prefixEnd - 1]; - return lps; -} -async function* readDelim(reader, delim) { - // Avoid unicode problems - const delimLen = delim.length; - const delimLPS = createLPS(delim); - let inputBuffer = new Deno.Buffer(); - const inspectArr = new Uint8Array(Math.max(1024, delimLen + 1)); - // Modified KMP - let inspectIndex = 0; - let matchIndex = 0; - while(true){ - const result = await reader.read(inspectArr); - if (result === null) { - // Yield last chunk. - yield inputBuffer.bytes(); - return; - } - if (result < 0) // Discard all remaining and silently fail. - return; - const sliceRead = inspectArr.subarray(0, result); - await Deno.writeAll(inputBuffer, sliceRead); - let sliceToProcess = inputBuffer.bytes(); - while(inspectIndex < sliceToProcess.length)if (sliceToProcess[inspectIndex] === delim[matchIndex]) { - inspectIndex++; - matchIndex++; - if (matchIndex === delimLen) { - // Full match - const matchEnd = inspectIndex - delimLen; - const readyBytes = sliceToProcess.subarray(0, matchEnd); - // Copy - const pendingBytes = sliceToProcess.slice(inspectIndex); - yield readyBytes; - // Reset match, different from KMP. - sliceToProcess = pendingBytes; - inspectIndex = 0; - matchIndex = 0; - } - } else if (matchIndex === 0) inspectIndex++; - else matchIndex = delimLPS[matchIndex - 1]; - // Keep inspectIndex and matchIndex. - inputBuffer = new Deno.Buffer(sliceToProcess); - } -} -async function* readStringDelim(reader, delim) { - const encoder = new TextEncoder(); - const decoder = new TextDecoder(); - for await (const chunk of readDelim(reader, encoder.encode(delim)))yield decoder.decode(chunk); -} -function findIndex(source, pat) { - const s = pat[0]; - for(let i = 0; i < source.length; i++){ - if (source[i] !== s) continue; - const pin = i; - let matched = 1; - let j = i; - while(matched < pat.length){ - j++; - if (source[j] !== pat[j - pin]) break; - matched++; - } - if (matched === pat.length) return pin; - } - return -1; -} -function concat(origin, b) { - const output = new Uint8Array(origin.length + b.length); - output.set(origin, 0); - output.set(b, origin.length); - return output; -} -// FROM https://github.com/denoland/deno/blob/b34628a26ab0187a827aa4ebe256e23178e25d39/cli/js/web/headers.ts#L9 -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/g; -const decoder = new TextDecoder(); -function decode(input) { - return decoder.decode(input); -} -const decode1 = decode; -const decode2 = decode1; -function str(buf) { - if (buf == null) return ""; - else return decode2(buf); -} -function charCode(s) { - return s.charCodeAt(0); -} -const concat1 = concat; -const concat2 = concat1; -class TextProtoReader { - /** readLine() reads a single line from the TextProtoReader, - * eliding the final \n or \r\n from the returned string. - */ async readLine() { - const s = await this.readLineSlice(); - if (s === null) return null; - return str(s); - } - /** ReadMIMEHeader reads a MIME-style header from r. - * The header is a sequence of possibly continued Key: Value lines - * ending in a blank line. - * The returned map m maps CanonicalMIMEHeaderKey(key) to a - * sequence of values in the same order encountered in the input. - * - * For example, consider this input: - * - * My-Key: Value 1 - * Long-Key: Even - * Longer Value - * My-Key: Value 2 - * - * Given that input, ReadMIMEHeader returns the map: - * - * map[string][]string{ - * "My-Key": {"Value 1", "Value 2"}, - * "Long-Key": {"Even Longer Value"}, - * } - */ async readMIMEHeader() { - const m = new Headers(); - let line; - // The first line cannot start with a leading space. - let buf = await this.r.peek(1); - if (buf === null) return null; - else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) line = await this.readLineSlice(); - buf = await this.r.peek(1); - if (buf === null) throw new Deno.errors.UnexpectedEof(); - else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) throw new Deno.errors.InvalidData(`malformed MIME header initial line: ${str(line)}`); - while(true){ - const kv = await this.readLineSlice(); // readContinuedLineSlice - if (kv === null) throw new Deno.errors.UnexpectedEof(); - if (kv.byteLength === 0) return m; - // Key ends at first colon - let i = kv.indexOf(charCode(":")); - if (i < 0) throw new Deno.errors.InvalidData(`malformed MIME header line: ${str(kv)}`); - //let key = canonicalMIMEHeaderKey(kv.subarray(0, endKey)); - const key = str(kv.subarray(0, i)); - // As per RFC 7230 field-name is a token, - // tokens consist of one or more chars. - // We could throw `Deno.errors.InvalidData` here, - // but better to be liberal in what we - // accept, so if we get an empty key, skip it. - if (key == "") continue; - // Skip initial spaces in value. - i++; // skip colon - while(i < kv.byteLength && (kv[i] == charCode(" ") || kv[i] == charCode("\t")))i++; - const value = str(kv.subarray(i)).replace(invalidHeaderCharRegex, encodeURI); - // In case of invalid header we swallow the error - // example: "Audio Mode" => invalid due to space in the key - try { - m.append(key, value); - } catch { - } - } - } - async readLineSlice() { - // this.closeDot(); - let line; - while(true){ - const r = await this.r.readLine(); - if (r === null) return null; - const { line: l , more } = r; - // Avoid the copy if the first call produced a full line. - if (!line && !more) { - // TODO(ry): - // This skipSpace() is definitely misplaced, but I don't know where it - // comes from nor how to fix it. - if (this.skipSpace(l) === 0) return new Uint8Array(0); - return l; - } - line = line ? concat2(line, l) : l; - if (!more) break; - } - return line; - } - skipSpace(l) { - let n = 0; - for(let i = 0; i < l.length; i++){ - if (l[i] === charCode(" ") || l[i] === charCode("\t")) continue; - n++; + else { + numBytesWritten = copyBytes2(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + this.flush(); + } + totalBytesWritten += numBytesWritten; + data = data.subarray(numBytesWritten); } - return n; + numBytesWritten = copyBytes2(data, this.buf, this.usedBufferBytes); + this.usedBufferBytes += numBytesWritten; + totalBytesWritten += numBytesWritten; + return totalBytesWritten; } - constructor(r1){ - this.r = r1; - this.r = r1; + constructor(writer2, size3 = DEFAULT_BUF_SIZE){ + super(); + this.writer = writer2; + if (size3 <= 0) size3 = DEFAULT_BUF_SIZE; + this.buf = new Uint8Array(size3); } } -const encoder = new TextEncoder(); -function encode(input) { - return encoder.encode(input); -} -const STATUS_TEXT = new Map([]); -function emptyReader() { - return { - read (_) { - return Promise.resolve(null); - } - }; +/** Generate longest proper prefix which is also suffix array. */ function createLPS(pat) { + const lps = new Uint8Array(pat.length); + lps[0] = 0; + let prefixEnd = 0; + let i = 1; + while(i < lps.length)if (pat[i] == pat[prefixEnd]) { + prefixEnd++; + lps[i] = prefixEnd; + i++; + } else if (prefixEnd === 0) { + lps[i] = 0; + i++; + } else prefixEnd = pat[prefixEnd - 1]; + return lps; } -function bodyReader(contentLength, r1) { - let totalRead = 0; - let finished = false; - async function read(buf) { - if (finished) return null; - let result; - const remaining = contentLength - totalRead; - if (remaining >= buf.byteLength) result = await r1.read(buf); - else { - const readBuf = buf.subarray(0, remaining); - result = await r1.read(readBuf); +async function* readDelim(reader, delim) { + // Avoid unicode problems + const delimLen = delim.length; + const delimLPS = createLPS(delim); + let inputBuffer = new Deno.Buffer(); + const inspectArr = new Uint8Array(Math.max(1024, delimLen + 1)); + // Modified KMP + let inspectIndex = 0; + let matchIndex = 0; + while(true){ + const result = await reader.read(inspectArr); + if (result === null) { + // Yield last chunk. + yield inputBuffer.bytes(); + return; } - if (result !== null) totalRead += result; - finished = totalRead === contentLength; - return result; + if (result < 0) // Discard all remaining and silently fail. + return; + const sliceRead = inspectArr.subarray(0, result); + await Deno.writeAll(inputBuffer, sliceRead); + let sliceToProcess = inputBuffer.bytes(); + while(inspectIndex < sliceToProcess.length)if (sliceToProcess[inspectIndex] === delim[matchIndex]) { + inspectIndex++; + matchIndex++; + if (matchIndex === delimLen) { + // Full match + const matchEnd = inspectIndex - delimLen; + const readyBytes = sliceToProcess.subarray(0, matchEnd); + // Copy + const pendingBytes = sliceToProcess.slice(inspectIndex); + yield readyBytes; + // Reset match, different from KMP. + sliceToProcess = pendingBytes; + inspectIndex = 0; + matchIndex = 0; + } + } else if (matchIndex === 0) inspectIndex++; + else matchIndex = delimLPS[matchIndex - 1]; + // Keep inspectIndex and matchIndex. + inputBuffer = new Deno.Buffer(sliceToProcess); } - return { - read - }; } -const bodyReader1 = bodyReader; -const bodyReader2 = bodyReader1; -const TextProtoReader1 = TextProtoReader; -const TextProtoReader2 = TextProtoReader1; -const assert4 = assert1; -const STATUS_TEXT1 = STATUS_TEXT; -const STATUS_TEXT2 = STATUS_TEXT1; +async function* readStringDelim(reader, delim) { + const encoder1 = new TextEncoder(); + const decoder1 = new TextDecoder(); + for await (const chunk of readDelim(reader, encoder1.encode(delim)))yield decoder1.decode(chunk); +} const BufWriter1 = BufWriter; const BufWriter2 = BufWriter1; -const BufReader1 = BufReader; -const BufReader2 = BufReader1; -function chunkedBodyReader(h, r1) { - // Based on https://tools.ietf.org/html/rfc2616#section-19.4.6 - const tp = new TextProtoReader2(r1); - let finished = false; - const chunks = []; - async function read(buf) { - if (finished) return null; - const [chunk] = chunks; - if (chunk) { - const chunkRemaining = chunk.data.byteLength - chunk.offset; - const readLength = Math.min(chunkRemaining, buf.byteLength); - for(let i = 0; i < readLength; i++)buf[i] = chunk.data[chunk.offset + i]; - chunk.offset += readLength; - if (chunk.offset === chunk.data.byteLength) { - chunks.shift(); - // Consume \r\n; - if (await tp.readLine() === null) throw new Deno.errors.UnexpectedEof(); - } - return readLength; - } - const line = await tp.readLine(); - if (line === null) throw new Deno.errors.UnexpectedEof(); - // TODO: handle chunk extension - const [chunkSizeString] = line.split(";"); - const chunkSize = parseInt(chunkSizeString, 16); - if (Number.isNaN(chunkSize) || chunkSize < 0) throw new Error("Invalid chunk size"); - if (chunkSize > 0) { - if (chunkSize > buf.byteLength) { - let eof = await r1.readFull(buf); - if (eof === null) throw new Deno.errors.UnexpectedEof(); - const restChunk = new Uint8Array(chunkSize - buf.byteLength); - eof = await r1.readFull(restChunk); - if (eof === null) throw new Deno.errors.UnexpectedEof(); - else chunks.push({ - offset: 0, - data: restChunk - }); - return buf.byteLength; - } else { - const bufToFill = buf.subarray(0, chunkSize); - const eof = await r1.readFull(bufToFill); - if (eof === null) throw new Deno.errors.UnexpectedEof(); - // Consume \r\n - if (await tp.readLine() === null) throw new Deno.errors.UnexpectedEof(); - return chunkSize; - } - } else { - assert4(chunkSize === 0); - // Consume \r\n - if (await r1.readLine() === null) throw new Deno.errors.UnexpectedEof(); - await readTrailers(h, r1); - finished = true; - return null; - } - } - return { - read - }; -} -const chunkedBodyReader1 = chunkedBodyReader; -const chunkedBodyReader2 = chunkedBodyReader1; -const emptyReader1 = emptyReader; -const emptyReader2 = emptyReader1; const BufWriter3 = BufWriter1; const encoder1 = encoder; const encoder2 = encoder1; -function isProhibidedForTrailer(key) { - const s = new Set([ - "transfer-encoding", - "content-length", - "trailer" - ]); - return s.has(key.toLowerCase()); -} -async function readTrailers(headers, r1) { - const trailers = parseTrailer(headers.get("trailer")); - if (trailers == null) return; - const trailerNames = [ - ...trailers.keys() - ]; - const tp = new TextProtoReader2(r1); - const result = await tp.readMIMEHeader(); - if (result == null) throw new Deno.errors.InvalidData("Missing trailer header."); - const undeclared = [ - ...result.keys() - ].filter((k)=>!trailerNames.includes(k) - ); - if (undeclared.length > 0) throw new Deno.errors.InvalidData(`Undeclared trailers: ${Deno.inspect(undeclared)}.`); - for (const [k, v] of result)headers.append(k, v); - const missingTrailers = trailerNames.filter((k1)=>!result.has(k1) - ); - if (missingTrailers.length > 0) throw new Deno.errors.InvalidData(`Missing trailers: ${Deno.inspect(missingTrailers)}.`); - headers.delete("trailer"); -} -function parseTrailer(field) { - if (field == null) return undefined; - const trailerNames = field.split(",").map((v)=>v.trim().toLowerCase() - ); - if (trailerNames.length === 0) throw new Deno.errors.InvalidData("Empty trailer header."); - const prohibited = trailerNames.filter((k)=>isProhibidedForTrailer(k) - ); - if (prohibited.length > 0) throw new Deno.errors.InvalidData(`Prohibited trailer names: ${Deno.inspect(prohibited)}.`); - return new Headers(trailerNames.map((key)=>[ - key, - "" - ] - )); -} -async function writeChunkedBody(w, r1) { - const writer = BufWriter3.create(w); - for await (const chunk of Deno.iter(r1)){ +async function writeChunkedBody(w, r2) { + const writer = BufWriter2.create(w); + for await (const chunk of Deno.iter(r2)){ if (chunk.byteLength <= 0) continue; const start = encoder2.encode(`${chunk.byteLength.toString(16)}\r\n`); const end = encoder2.encode("\r\n"); @@ -834,7 +823,7 @@ async function writeTrailers(w, headers, trailers) { if (trailer === null) throw new TypeError("Missing trailer header."); const transferEncoding = headers.get("transfer-encoding"); if (transferEncoding === null || !transferEncoding.match(/^chunked/)) throw new TypeError(`Trailers are only allowed for "transfer-encoding: chunked", got "transfer-encoding: ${transferEncoding}".`); - const writer = BufWriter3.create(w); + const writer = BufWriter2.create(w); const trailerNames = trailer.split(",").map((s)=>s.trim().toLowerCase() ); const prohibitedTrailers = trailerNames.filter((k)=>isProhibidedForTrailer(k) @@ -849,44 +838,45 @@ async function writeTrailers(w, headers, trailers) { await writer.write(encoder2.encode("\r\n")); await writer.flush(); } -async function writeResponse(w, r1) { +const STATUS_TEXT = new Map([]); +const STATUS_TEXT1 = STATUS_TEXT; +const STATUS_TEXT2 = STATUS_TEXT1; +async function writeResponse(w, r2) { const protoMajor = 1; const protoMinor = 1; - const statusCode = r1.status || 200; + const statusCode = r2.status || 200; const statusText = STATUS_TEXT2.get(statusCode); - const writer = BufWriter3.create(w); + const writer = BufWriter2.create(w); if (!statusText) throw new Deno.errors.InvalidData("Bad status code"); - if (!r1.body) r1.body = new Uint8Array(); - if (typeof r1.body === "string") r1.body = encoder2.encode(r1.body); + if (!r2.body) r2.body = new Uint8Array(); + if (typeof r2.body === "string") r2.body = encoder2.encode(r2.body); let out = `HTTP/${protoMajor}.${protoMinor} ${statusCode} ${statusText}\r\n`; - const headers = r1.headers ?? new Headers(); - if (r1.body && !headers.get("content-length")) { - if (r1.body instanceof Uint8Array) out += `content-length: ${r1.body.byteLength}\r\n`; + const headers = r2.headers ?? new Headers(); + if (r2.body && !headers.get("content-length")) { + if (r2.body instanceof Uint8Array) out += `content-length: ${r2.body.byteLength}\r\n`; else if (!headers.get("transfer-encoding")) out += "transfer-encoding: chunked\r\n"; } for (const [key, value] of headers)out += `${key}: ${value}\r\n`; out += `\r\n`; const header = encoder2.encode(out); const n = await writer.write(header); - assert4(n === header.byteLength); - if (r1.body instanceof Uint8Array) { - const n1 = await writer.write(r1.body); - assert4(n1 === r1.body.byteLength); + assert3(n === header.byteLength); + if (r2.body instanceof Uint8Array) { + const n1 = await writer.write(r2.body); + assert3(n1 === r2.body.byteLength); } else if (headers.has("content-length")) { const contentLength = headers.get("content-length"); - assert4(contentLength != null); + assert3(contentLength != null); const bodyLength = parseInt(contentLength); - const n1 = await Deno.copy(r1.body, writer); - assert4(n1 === bodyLength); - } else await writeChunkedBody(writer, r1.body); - if (r1.trailers) { - const t = await r1.trailers(); + const n1 = await Deno.copy(r2.body, writer); + assert3(n1 === bodyLength); + } else await writeChunkedBody(writer, r2.body); + if (r2.trailers) { + const t = await r2.trailers(); await writeTrailers(writer, headers, t); } await writer.flush(); } -const writeResponse1 = writeResponse; -const writeResponse2 = writeResponse1; function parseHTTPVersion(vers) { switch(vers){ case "HTTP/1.1": @@ -919,6 +909,14 @@ function parseHTTPVersion(vers) { } throw new Error(`malformed HTTP version ${vers}`); } +const bodyReader1 = bodyReader; +const bodyReader2 = bodyReader1; +const chunkedBodyReader1 = chunkedBodyReader; +const chunkedBodyReader2 = chunkedBodyReader1; +const emptyReader1 = emptyReader; +const emptyReader2 = emptyReader1; +const writeResponse1 = writeResponse; +const writeResponse2 = writeResponse1; function deferred() { let methods; const promise = new Promise((resolve, reject)=>{ @@ -931,6 +929,8 @@ function deferred() { } const deferred1 = deferred; const deferred2 = deferred1; +const deferred3 = deferred1; +const deferred4 = deferred3; class ServerRequest { /** * Value of Content-Length header. @@ -960,7 +960,7 @@ class ServerRequest { if (transferEncoding != null) { const parts = transferEncoding.split(",").map((e)=>e.trim().toLowerCase() ); - assert2(parts.includes("chunked"), 'transfer-encoding must include "chunked" if content-length is not set'); + assert4(parts.includes("chunked"), 'transfer-encoding must include "chunked" if content-length is not set'); this._body = chunkedBodyReader2(this.headers, this.r); } else // Neither content-length nor transfer-encoding: chunked this._body = emptyReader2(); @@ -996,12 +996,15 @@ class ServerRequest { this.finalized = true; } constructor(){ - this.done = deferred2(); + this.done = deferred4(); this._contentLength = undefined; this._body = null; this.finalized = false; } } +var tmp = Symbol.asyncIterator; +const BufReader1 = BufReader; +const BufReader2 = BufReader1; const ServerRequest1 = ServerRequest; const ServerRequest2 = ServerRequest1; async function readRequest(conn, bufr) { @@ -1019,8 +1022,6 @@ async function readRequest(conn, bufr) { fixLength(req); return req; } -const deferred3 = deferred; -const deferred4 = deferred3; function fixLength(req) { const contentLength = req.headers.get("Content-Length"); if (contentLength) { @@ -1041,7 +1042,11 @@ function fixLength(req) { throw new Error("http: Transfer-Encoding and Content-Length cannot be send together"); } } -var tmp = Symbol.asyncIterator; +const readRequest1 = readRequest; +const readRequest2 = readRequest1; +const encode1 = encode; +const encode2 = encode1; +var tmp1 = Symbol.asyncIterator; class MuxAsyncIterator { add(iterator) { ++this.iteratorCount; @@ -1076,26 +1081,22 @@ class MuxAsyncIterator { } // Clear the `yields` list and reset the `signal` promise. this.yields.length = 0; - this.signal = deferred4(); + this.signal = deferred2(); } } - [tmp]() { + [tmp1]() { return this.iterate(); } constructor(){ this.iteratorCount = 0; this.yields = []; this.throws = []; - this.signal = deferred4(); + this.signal = deferred2(); } } -const readRequest1 = readRequest; -const readRequest2 = readRequest1; -const encode1 = encode; -const encode2 = encode1; -var tmp1 = Symbol.asyncIterator; const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; +const MuxAsyncIterator3 = MuxAsyncIterator2; class Server { close() { this.closing = true; @@ -1110,7 +1111,7 @@ class Server { // Yields all HTTP requests on a single TCP connection. async *iterateHttpRequests(conn) { const reader = new BufReader2(conn); - const writer = new BufWriter2(conn); + const writer = new BufWriter3(conn); while(!this.closing){ let request; try { @@ -1172,8 +1173,8 @@ class Server { // Yield the requests that arrive on the just-accepted connection. yield* this.iterateHttpRequests(conn); } - [tmp1]() { - const mux = new MuxAsyncIterator2(); + [tmp]() { + const mux = new MuxAsyncIterator3(); mux.add(this.acceptConnAndIterateHttpRequests(mux)); return mux.iterate(); } diff --git a/spack/tests/pass/deno-001/simple-1/output/entry.js b/spack/tests/pass/deno-001/simple-1/output/entry.js index 00342421c7b0..c0d9915a6aa1 100644 --- a/spack/tests/pass/deno-001/simple-1/output/entry.js +++ b/spack/tests/pass/deno-001/simple-1/output/entry.js @@ -247,6 +247,8 @@ function deferred() { } const deferred1 = deferred; const deferred2 = deferred1; +const deferred3 = deferred1; +const deferred4 = deferred3; class ServerRequest { /** * Value of Content-Length header. @@ -312,12 +314,13 @@ class ServerRequest { this.finalized = true; } constructor(){ - this.done = deferred2(); + this.done = deferred4(); this._contentLength = undefined; this._body = null; this.finalized = false; } } +var tmp = Symbol.asyncIterator; const ServerRequest1 = ServerRequest; const ServerRequest2 = ServerRequest1; async function readRequest(conn, bufr) { @@ -335,8 +338,6 @@ async function readRequest(conn, bufr) { fixLength(req); return req; } -const deferred3 = deferred; -const deferred4 = deferred3; function fixLength(req) { const contentLength = req.headers.get("Content-Length"); if (contentLength) { @@ -357,7 +358,9 @@ function fixLength(req) { throw new Error("http: Transfer-Encoding and Content-Length cannot be send together"); } } -var tmp = Symbol.asyncIterator; +const readRequest1 = readRequest; +const readRequest2 = readRequest1; +var tmp1 = Symbol.asyncIterator; class MuxAsyncIterator { add(iterator) { ++this.iteratorCount; @@ -392,24 +395,22 @@ class MuxAsyncIterator { } // Clear the `yields` list and reset the `signal` promise. this.yields.length = 0; - this.signal = deferred4(); + this.signal = deferred2(); } } - [tmp]() { + [tmp1]() { return this.iterate(); } constructor(){ this.iteratorCount = 0; this.yields = []; this.throws = []; - this.signal = deferred4(); + this.signal = deferred2(); } } -const readRequest1 = readRequest; -const readRequest2 = readRequest1; -var tmp1 = Symbol.asyncIterator; const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; +const MuxAsyncIterator3 = MuxAsyncIterator2; class Server { close() { this.closing = true; @@ -486,8 +487,8 @@ class Server { // Yield the requests that arrive on the just-accepted connection. yield* this.iterateHttpRequests(conn); } - [tmp1]() { - const mux = new MuxAsyncIterator2(); + [tmp]() { + const mux = new MuxAsyncIterator3(); mux.add(this.acceptConnAndIterateHttpRequests(mux)); return mux.iterate(); } diff --git a/spack/tests/pass/deno-001/simple-2/output/entry.js b/spack/tests/pass/deno-001/simple-2/output/entry.js index 96f8d5bc7936..6082eee9af8c 100644 --- a/spack/tests/pass/deno-001/simple-2/output/entry.js +++ b/spack/tests/pass/deno-001/simple-2/output/entry.js @@ -2,9 +2,11 @@ function deferred() { } const deferred1 = deferred; const deferred2 = deferred1; +const deferred3 = deferred1; +const deferred4 = deferred3; class ServerRequest { constructor(){ - this.done = deferred2(); + this.done = deferred4(); } } const ServerRequest1 = ServerRequest; @@ -12,22 +14,21 @@ const ServerRequest2 = ServerRequest1; console.log(ServerRequest2); async function writeResponse(w, r) { } -const writeResponse1 = writeResponse; -const writeResponse2 = writeResponse1; async function readRequest(conn, bufr) { } +const writeResponse1 = writeResponse; +const writeResponse2 = writeResponse1; const readRequest1 = readRequest; const readRequest2 = readRequest1; -const deferred3 = deferred; -const deferred4 = deferred3; class MuxAsyncIterator { constructor(){ - this.signal = deferred4(); + this.signal = deferred2(); } } const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; -console.log(deferred2, writeResponse2, readRequest2, MuxAsyncIterator2); +const MuxAsyncIterator3 = MuxAsyncIterator2; +console.log(deferred4, writeResponse2, readRequest2, MuxAsyncIterator3); async function listenAndServe(addr, handler) { } const listenAndServe1 = listenAndServe; diff --git a/spack/tests/pass/deno-001/simple-3/output/entry.js b/spack/tests/pass/deno-001/simple-3/output/entry.js index e097d25ea73d..a029703a6633 100644 --- a/spack/tests/pass/deno-001/simple-3/output/entry.js +++ b/spack/tests/pass/deno-001/simple-3/output/entry.js @@ -2,13 +2,14 @@ function deferred() { } const deferred1 = deferred; const deferred2 = deferred1; +const deferred3 = deferred1; +const deferred4 = deferred3; class MuxAsyncIterator { constructor(){ this.signal = deferred2(); } } -const deferred3 = deferred; -const deferred4 = deferred3; const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; -console.log(deferred4, MuxAsyncIterator2); +const MuxAsyncIterator3 = MuxAsyncIterator2; +console.log(deferred4, MuxAsyncIterator3); diff --git a/spack/tests/pass/deno-001/simple-4/output/entry.js b/spack/tests/pass/deno-001/simple-4/output/entry.js index 22b1a2334753..a029703a6633 100644 --- a/spack/tests/pass/deno-001/simple-4/output/entry.js +++ b/spack/tests/pass/deno-001/simple-4/output/entry.js @@ -2,14 +2,14 @@ function deferred() { } const deferred1 = deferred; const deferred2 = deferred1; -const deferred3 = deferred2; -const deferred4 = deferred1; +const deferred3 = deferred1; +const deferred4 = deferred3; class MuxAsyncIterator { constructor(){ - this.signal = deferred4(); + this.signal = deferred2(); } } const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; const MuxAsyncIterator3 = MuxAsyncIterator2; -console.log(deferred3, MuxAsyncIterator3); +console.log(deferred4, MuxAsyncIterator3); diff --git a/spack/tests/pass/deno-001/simple-5/output/entry.js b/spack/tests/pass/deno-001/simple-5/output/entry.js index 5719ccb64deb..26c57dc424df 100644 --- a/spack/tests/pass/deno-001/simple-5/output/entry.js +++ b/spack/tests/pass/deno-001/simple-5/output/entry.js @@ -1,10 +1,10 @@ function deferred() { } -function MuxAsyncIterator() { -} const deferred1 = deferred; const deferred2 = deferred1; const deferred3 = deferred2; +function MuxAsyncIterator() { +} const MuxAsyncIterator1 = MuxAsyncIterator; const MuxAsyncIterator2 = MuxAsyncIterator1; const MuxAsyncIterator3 = MuxAsyncIterator2; diff --git a/spack/tests/pass/drop-unused/export/default-mixed/output/entry.js b/spack/tests/pass/drop-unused/export/default-mixed/output/entry.js index 5f793f250771..56bbfcc51479 100644 --- a/spack/tests/pass/drop-unused/export/default-mixed/output/entry.js +++ b/spack/tests/pass/drop-unused/export/default-mixed/output/entry.js @@ -1,4 +1,6 @@ -const foo2 = 1; -const __default = foo2; -const foo1 = __default; +const foo = 1; +const __default = foo; +const __default1 = __default; +const foo1 = __default1; +const foo2 = foo1; export { foo1 as foo }; diff --git a/spack/tests/pass/drop-unused/export/named/output/entry.js b/spack/tests/pass/drop-unused/export/named/output/entry.js index 7f076d502839..bb7fb50b1fb2 100644 --- a/spack/tests/pass/drop-unused/export/named/output/entry.js +++ b/spack/tests/pass/drop-unused/export/named/output/entry.js @@ -1,2 +1,3 @@ const foo1 = "a"; export { foo1 as foo }; +const foo2 = foo1; diff --git a/spack/tests/pass/drop-unused/side-effect/import-multi/output/entry.js b/spack/tests/pass/drop-unused/side-effect/import-multi/output/entry.js index b16692f3e1d1..756f28690d2a 100644 --- a/spack/tests/pass/drop-unused/side-effect/import-multi/output/entry.js +++ b/spack/tests/pass/drop-unused/side-effect/import-multi/output/entry.js @@ -1,9 +1,9 @@ function a() { } -function b() { -} const a1 = a; const a2 = a1; +function b() { +} const b1 = b; const b2 = b1; console.log(a2, b2); diff --git a/spack/tests/pass/export-all/output/entry.js b/spack/tests/pass/export-all/output/entry.js index 1117119e724b..6977cd439993 100644 --- a/spack/tests/pass/export-all/output/entry.js +++ b/spack/tests/pass/export-all/output/entry.js @@ -1,3 +1,7 @@ -export const DEBUG = true; -export class B { +class B { } +const DEBUG = true; +const B1 = B; +const DEBUG1 = DEBUG; +export { B as B }; +export { DEBUG as DEBUG }; diff --git a/spack/tests/pass/export-star-namespace/issue-1109/output/entry.js b/spack/tests/pass/export-star-namespace/issue-1109/output/entry.js index c08ff3b3f1bf..80988ed07560 100644 --- a/spack/tests/pass/export-star-namespace/issue-1109/output/entry.js +++ b/spack/tests/pass/export-star-namespace/issue-1109/output/entry.js @@ -5,4 +5,5 @@ const mod = function() { }; }(); const _a = mod; +const a = _a; export { _a as a }; diff --git a/spack/tests/pass/export/all-1/multiple/output/entry.js b/spack/tests/pass/export/all-1/multiple/output/entry.js index e9a32659efd6..3e81e76a3ce7 100644 --- a/spack/tests/pass/export/all-1/multiple/output/entry.js +++ b/spack/tests/pass/export/all-1/multiple/output/entry.js @@ -1,10 +1,18 @@ -export const [a, b, c] = [ - 1, - 2, - 3 -]; -export const [d, e, f] = [ +const [d, e, f] = [ 4, 5, 6 ]; +const [a, b, c] = [ + 1, + 2, + 3 +]; +const d1 = d; +const e1 = e; +const f1 = f; +const a1 = a; +const b1 = b; +const c1 = c; +export { d as d, e as e, f as f }; +export { a as a, b as b, c as c }; diff --git a/spack/tests/pass/export/all-2/output/entry.js b/spack/tests/pass/export/all-2/output/entry.js index 215da027d62c..86dbf25a5fca 100644 --- a/spack/tests/pass/export/all-2/output/entry.js +++ b/spack/tests/pass/export/all-2/output/entry.js @@ -3,7 +3,11 @@ class Root { const Root1 = Root; const Root2 = Root1; const Root3 = Root1; -export class A extends Root3 { +class B extends Root3 { } -export class B extends Root2 { +class A extends Root2 { } +const B1 = B; +const A1 = A; +export { B as B }; +export { A as A }; diff --git a/spack/tests/pass/export/all-nested-1/output/entry.js b/spack/tests/pass/export/all-nested-1/output/entry.js index 26b8d7a37c81..da33e1673e64 100644 --- a/spack/tests/pass/export/all-nested-1/output/entry.js +++ b/spack/tests/pass/export/all-nested-1/output/entry.js @@ -1,3 +1,9 @@ -export const a = 1; -export const b = 2; -export const c = 3; +const a = 1; +const b = 2; +const c = 3; +const a1 = a; +const b1 = b; +const c1 = c; +export { a as a }; +export { b as b }; +export { c as c }; diff --git a/spack/tests/pass/export/complex-1/output/entry.js b/spack/tests/pass/export/complex-1/output/entry.js index fb1694004fb7..d77785740b9a 100644 --- a/spack/tests/pass/export/complex-1/output/entry.js +++ b/spack/tests/pass/export/complex-1/output/entry.js @@ -1,8 +1,10 @@ -const b3 = '1'; -const a2 = '1'; -const b1 = b3; +const b = '1'; +const a = '1'; +const b1 = b; const b2 = b1; +const b3 = b1; console.log(b2); -const a1 = a2; +const a1 = a; +const a2 = a1; export { a1 as a }; export { b1 as b }; diff --git a/spack/tests/pass/export/mixed-all-and-const/output/entry.js b/spack/tests/pass/export/mixed-all-and-const/output/entry.js index 72ab60e17a25..2a3e4de6654c 100644 --- a/spack/tests/pass/export/mixed-all-and-const/output/entry.js +++ b/spack/tests/pass/export/mixed-all-and-const/output/entry.js @@ -1,2 +1,6 @@ -export const a = 1; -export const b = 2; +const b = 2; +const a = 1; +const b1 = b; +const a1 = a; +export { b as b }; +export { a as a }; diff --git a/spack/tests/pass/import-with-export/simple-1/output/entry.js b/spack/tests/pass/import-with-export/simple-1/output/entry.js index 99c7d736fd84..fb90bc607974 100644 --- a/spack/tests/pass/import-with-export/simple-1/output/entry.js +++ b/spack/tests/pass/import-with-export/simple-1/output/entry.js @@ -1,6 +1,11 @@ -export const a = 1; -export const b = 2; -export const c = 3; +const a = 1; +const b = 2; +const c = 3; const a1 = a; const a2 = a1; console.log(a2); +const b1 = b; +const c1 = c; +export { a as a }; +export { b as b }; +export { c as c }; diff --git a/spack/tests/pass/import/commons-default/output/entry.js b/spack/tests/pass/import/commons-default/output/entry.js index 5ffe6603a73e..131c98ef5384 100644 --- a/spack/tests/pass/import/commons-default/output/entry.js +++ b/spack/tests/pass/import/commons-default/output/entry.js @@ -1,14 +1,17 @@ class Common { } const __default = Common; -const Common1 = __default; -const Common2 = __default; +const __default1 = __default; +const Common1 = __default1; +const Common2 = __default1; class A extends Common2 { } +const __default2 = A; +const __default3 = __default2; +const A1 = __default3; class B extends Common1 { } -const __default1 = B; -const B1 = __default1; -const __default2 = A; -const A1 = __default2; +const __default4 = B; +const __default5 = __default4; +const B1 = __default5; console.log(A1, B1); diff --git a/spack/tests/pass/import/commons-named/output/entry.js b/spack/tests/pass/import/commons-named/output/entry.js index 4e657eb1b676..12f453f5c8e1 100644 --- a/spack/tests/pass/import/commons-named/output/entry.js +++ b/spack/tests/pass/import/commons-named/output/entry.js @@ -5,10 +5,12 @@ const Common2 = Common1; const Common3 = Common1; class A extends Common3 { } +const __default = A; +const __default1 = __default; +const A1 = __default1; class B extends Common2 { } -const __default = B; -const B1 = __default; -const __default1 = A; -const A1 = __default1; +const __default2 = B; +const __default3 = __default2; +const B1 = __default3; console.log(A1, B1); diff --git a/spack/tests/pass/import/default/named-class/output/entry.js b/spack/tests/pass/import/default/named-class/output/entry.js index 675bcbfedf50..64a4bdbb6364 100644 --- a/spack/tests/pass/import/default/named-class/output/entry.js +++ b/spack/tests/pass/import/default/named-class/output/entry.js @@ -1,5 +1,6 @@ class MyClass { } const __default = MyClass; -const A = __default; +const __default1 = __default; +const A = __default1; console.log(A); diff --git a/spack/tests/pass/import/default/unnamed-class/output/entry.js b/spack/tests/pass/import/default/unnamed-class/output/entry.js index 13b3a16d88f5..f770b9c9d822 100644 --- a/spack/tests/pass/import/default/unnamed-class/output/entry.js +++ b/spack/tests/pass/import/default/unnamed-class/output/entry.js @@ -1,4 +1,5 @@ const __default = class { }; -const A = __default; +const __default1 = __default; +const A = __default1; console.log(A); diff --git a/spack/tests/pass/import/name-conflict/simple/output/entry.js b/spack/tests/pass/import/name-conflict/simple/output/entry.js index ea64caa7c6d9..913a32a6994b 100644 --- a/spack/tests/pass/import/name-conflict/simple/output/entry.js +++ b/spack/tests/pass/import/name-conflict/simple/output/entry.js @@ -1,6 +1,6 @@ -const foo = 10; -const bar = foo; -const foo1 = 5; +const foo = 5; +const foo1 = 10; +const bar = foo1; const bar1 = bar; const bar2 = bar1; -console.log(foo1, bar2); +console.log(foo, bar2); diff --git a/spack/tests/pass/import/namespace/name-conflict/in-entry/output/entry.js b/spack/tests/pass/import/namespace/name-conflict/in-entry/output/entry.js index 78d114bb8c59..df9e9acbf4ad 100644 --- a/spack/tests/pass/import/namespace/name-conflict/in-entry/output/entry.js +++ b/spack/tests/pass/import/namespace/name-conflict/in-entry/output/entry.js @@ -1,9 +1,9 @@ -function a() { -} function foo() { } +function a() { +} function foo1() { } const a1 = a; -const foo2 = foo; -console.log(foo1(), a1(), foo2()); +const foo2 = foo1; +console.log(foo(), a1(), foo2()); diff --git a/spack/tests/pass/import/simple-alias/output/entry.js b/spack/tests/pass/import/simple-alias/output/entry.js index b08a870187b2..30f4c6677ce8 100644 --- a/spack/tests/pass/import/simple-alias/output/entry.js +++ b/spack/tests/pass/import/simple-alias/output/entry.js @@ -1,4 +1,5 @@ const unnamed = 1; const __default = unnamed; -const a = __default; +const __default1 = __default; +const a = __default1; console.log(a); diff --git a/spack/tests/pass/import/star-export/output/entry.js b/spack/tests/pass/import/star-export/output/entry.js index 51f4c224f5e0..ca10c738208c 100644 --- a/spack/tests/pass/import/star-export/output/entry.js +++ b/spack/tests/pass/import/star-export/output/entry.js @@ -6,4 +6,5 @@ const mod = function() { }; }(); const _a = mod; +const a = _a; export { _a as a }; diff --git a/spack/tests/pass/issue-1138/example-1/output/entry.js b/spack/tests/pass/issue-1138/example-1/output/entry.js index 81cf4a5dc446..36b745a13274 100644 --- a/spack/tests/pass/issue-1138/example-1/output/entry.js +++ b/spack/tests/pass/issue-1138/example-1/output/entry.js @@ -1,6 +1,6 @@ -var a = "a"; var o = { }; +var a = "a"; const a1 = a; const a2 = a1; const defaultA = a2; diff --git a/spack/tests/pass/issue-1138/example-2/output/entry.js b/spack/tests/pass/issue-1138/example-2/output/entry.js index d60eadd60164..4a3ae3ef8f9c 100644 --- a/spack/tests/pass/issue-1138/example-2/output/entry.js +++ b/spack/tests/pass/issue-1138/example-2/output/entry.js @@ -1,6 +1,6 @@ -var defaultA = "a"; var o = { }; +var defaultA = "a"; const defaultA1 = defaultA; const defaultA2 = defaultA1; const defaultA3 = defaultA2; diff --git a/spack/tests/pass/issue-1138/example-3/output/entry.js b/spack/tests/pass/issue-1138/example-3/output/entry.js index 2aa0ef5478aa..b49fd123d8d5 100644 --- a/spack/tests/pass/issue-1138/example-3/output/entry.js +++ b/spack/tests/pass/issue-1138/example-3/output/entry.js @@ -1,6 +1,6 @@ -const a = "a"; const o = { }; +const a = "a"; const a1 = a; const a2 = a1; const defaultA = a2; diff --git a/spack/tests/pass/issue-1139/example-1/output/entry.js b/spack/tests/pass/issue-1139/example-1/output/entry.js index 98a7931201d4..6b6c6c74a892 100644 --- a/spack/tests/pass/issue-1139/example-1/output/entry.js +++ b/spack/tests/pass/issue-1139/example-1/output/entry.js @@ -1,11 +1,11 @@ -function f2() { - console.log("f2"); -} function f1() { console.log("f1"); } +function f2() { + console.log("f2"); +} const f11 = f1; -export { f11 as f1 }; f11(); const f21 = f2; f21(); +export { f1 as f1 }; diff --git a/spack/tests/pass/issue-1139/example-2/output/entry.js b/spack/tests/pass/issue-1139/example-2/output/entry.js index 0f312344d172..36aa5b53a49f 100644 --- a/spack/tests/pass/issue-1139/example-2/output/entry.js +++ b/spack/tests/pass/issue-1139/example-2/output/entry.js @@ -1,9 +1,9 @@ -function f2() { - console.log("f2"); -} function f1() { console.log("f1"); } +function f2() { + console.log("f2"); +} const f11 = f1; f11(); const f21 = f2; diff --git a/spack/tests/pass/merge/basic/output/entry.js b/spack/tests/pass/merge/basic/output/entry.js index a913b293c68e..e370754cf24e 100644 --- a/spack/tests/pass/merge/basic/output/entry.js +++ b/spack/tests/pass/merge/basic/output/entry.js @@ -1,7 +1,9 @@ -const a3 = 'a.js'; -const b3 = 'b.js'; -const a1 = a3; +const a = 'a.js'; +const a1 = a; const a2 = a1; -const b1 = b3; +const a3 = a2; +const b = 'b.js'; +const b1 = b; const b2 = b1; +const b3 = b2; export { a2 as a, b2 as b }; diff --git a/spack/tests/pass/merge/name-conflict/simple/output/entry.js b/spack/tests/pass/merge/name-conflict/simple/output/entry.js index d729265e7b46..7e9c9630cfea 100644 --- a/spack/tests/pass/merge/name-conflict/simple/output/entry.js +++ b/spack/tests/pass/merge/name-conflict/simple/output/entry.js @@ -1,13 +1,15 @@ -const a3 = foo1(); +const a = foo1(); function foo1() { return 1; } -const b3 = foo2(); +const a1 = a; +const a2 = a1; +const a3 = a2; +const b = foo2(); function foo2() { return 2; } -const a1 = a3; -const a2 = a1; -const b1 = b3; +const b1 = b; const b2 = b1; +const b3 = b2; export { a2 as a, b2 as b }; diff --git a/spack/tests/pass/node-modules/library/simple/output/entry.js b/spack/tests/pass/node-modules/library/simple/output/entry.js index 7f58571374b9..16b7e8632f0f 100644 --- a/spack/tests/pass/node-modules/library/simple/output/entry.js +++ b/spack/tests/pass/node-modules/library/simple/output/entry.js @@ -193,7 +193,6 @@ var load = __spack_require__.bind(void 0, function(module, exports) { }; }); module.exports = load1(); - const progress = module.exports; }); var { default: progress } = load(); console.log(progress); diff --git a/spack/tests/pass/pr-1105/example-10/output/entry.js b/spack/tests/pass/pr-1105/example-10/output/entry.js index 96c50d7f96ab..69aa9ee5bcb8 100644 --- a/spack/tests/pass/pr-1105/example-10/output/entry.js +++ b/spack/tests/pass/pr-1105/example-10/output/entry.js @@ -17,6 +17,8 @@ const mod1 = function() { }(); const _j = mod1; const k = globalThis.value ? _i : _j; -const { a: a2 , } = k; -const a1 = a2; +const { a , } = k; +const a1 = a; +const a2 = a1; export { a1 as a, b as b }; +const b1 = b; diff --git a/spack/tests/pass/pr-1105/example-2/output/entry.js b/spack/tests/pass/pr-1105/example-2/output/entry.js index bcad0c96a9ea..10d575566d5d 100644 --- a/spack/tests/pass/pr-1105/example-2/output/entry.js +++ b/spack/tests/pass/pr-1105/example-2/output/entry.js @@ -5,11 +5,12 @@ const mod = function() { const c = "c"; class C { } - const __default = C; const c1 = c; + const __default = C; + const __default1 = __default; return { - c, - default: __default + c: c1, + default: __default1 }; }(); const c = mod; diff --git a/spack/tests/pass/pr-1105/example-5/output/entry.js b/spack/tests/pass/pr-1105/example-5/output/entry.js index bcab92c51b7c..209bbe31a63d 100644 --- a/spack/tests/pass/pr-1105/example-5/output/entry.js +++ b/spack/tests/pass/pr-1105/example-5/output/entry.js @@ -1,4 +1,5 @@ const a = "a"; const a1 = a; const a2 = a1; -console.log(a2); +const a3 = a2; +console.log(a3); diff --git a/spack/tests/pass/pr-1105/example-9-js/output/entry.js b/spack/tests/pass/pr-1105/example-9-js/output/entry.js index 1e1549daebac..1e2e4d2903fa 100644 --- a/spack/tests/pass/pr-1105/example-9-js/output/entry.js +++ b/spack/tests/pass/pr-1105/example-9-js/output/entry.js @@ -5,4 +5,5 @@ const mod = function() { }; }(); const _a = mod; +const a = _a; export { _a as a }; diff --git a/spack/tests/pass/pr-1105/example-9-ts/output/entry.js b/spack/tests/pass/pr-1105/example-9-ts/output/entry.js index 1e1549daebac..1e2e4d2903fa 100644 --- a/spack/tests/pass/pr-1105/example-9-ts/output/entry.js +++ b/spack/tests/pass/pr-1105/example-9-ts/output/entry.js @@ -5,4 +5,5 @@ const mod = function() { }; }(); const _a = mod; +const a = _a; export { _a as a }; diff --git a/spack/tests/pass/reexport/default-1-simple/output/entry.js b/spack/tests/pass/reexport/default-1-simple/output/entry.js index 8b69425f1f63..b053df36cb0e 100644 --- a/spack/tests/pass/reexport/default-1-simple/output/entry.js +++ b/spack/tests/pass/reexport/default-1-simple/output/entry.js @@ -1,7 +1,9 @@ const b = 1; console.log('b'); const __default = b; -const a1 = __default; +const __default1 = __default; +const a1 = __default1; console.log('a.js'); export { a1 as a }; console.log('entry'); +const a2 = a1; diff --git a/spack/tests/pass/reexport/named-1-alias/output/entry.js b/spack/tests/pass/reexport/named-1-alias/output/entry.js index 46ecab0e3fdf..282d8464716e 100644 --- a/spack/tests/pass/reexport/named-1-alias/output/entry.js +++ b/spack/tests/pass/reexport/named-1-alias/output/entry.js @@ -4,3 +4,4 @@ const b1 = b; const a1 = b1; console.log('a'); export { a1 as a }; +const a2 = a1; diff --git a/spack/tests/pass/reexport/named-1-orig/output/entry.js b/spack/tests/pass/reexport/named-1-orig/output/entry.js index ed9adb154e1f..a754033f6fbf 100644 --- a/spack/tests/pass/reexport/named-1-orig/output/entry.js +++ b/spack/tests/pass/reexport/named-1-orig/output/entry.js @@ -4,3 +4,4 @@ const b1 = b; const b2 = b1; console.log('a'); export { b2 as a }; +const a = b2; diff --git a/spack/tests/pass/reexport/named-2-nested/output/entry.js b/spack/tests/pass/reexport/named-2-nested/output/entry.js index 3005d5812048..58fee040c1c5 100644 --- a/spack/tests/pass/reexport/named-2-nested/output/entry.js +++ b/spack/tests/pass/reexport/named-2-nested/output/entry.js @@ -7,3 +7,4 @@ const b1 = b; console.log('a'); export { b1 as a }; console.log('entry'); +const a = b1; diff --git a/spack/tests/pass/reexport/named-3-var/output/entry.js b/spack/tests/pass/reexport/named-3-var/output/entry.js index 5ee16126379b..8643db3da54f 100644 --- a/spack/tests/pass/reexport/named-3-var/output/entry.js +++ b/spack/tests/pass/reexport/named-3-var/output/entry.js @@ -7,3 +7,4 @@ const a1 = b; console.log('a'); export { a1 as a }; console.log('entry'); +const a2 = a1; diff --git a/spack/tests/pass/reexport/named-4-fn/output/entry.js b/spack/tests/pass/reexport/named-4-fn/output/entry.js index e69756206a4e..606997a5986d 100644 --- a/spack/tests/pass/reexport/named-4-fn/output/entry.js +++ b/spack/tests/pass/reexport/named-4-fn/output/entry.js @@ -6,3 +6,4 @@ const b1 = b; const b2 = b1; console.log('a'); export { b2 as a }; +const a = b2; diff --git a/spack/tests/pass/reexport/named-5-class/output/entry.js b/spack/tests/pass/reexport/named-5-class/output/entry.js index c099e5cd2f11..3c963593cc57 100644 --- a/spack/tests/pass/reexport/named-5-class/output/entry.js +++ b/spack/tests/pass/reexport/named-5-class/output/entry.js @@ -5,3 +5,4 @@ const b1 = b; const b2 = b1; console.log('a'); export { b2 as a }; +const a = b2; diff --git a/spack/tests/pass/reexport/recursive-mini/output/entry.js b/spack/tests/pass/reexport/recursive-mini/output/entry.js index 8ed18552a4b9..b1747be521c2 100644 --- a/spack/tests/pass/reexport/recursive-mini/output/entry.js +++ b/spack/tests/pass/reexport/recursive-mini/output/entry.js @@ -5,3 +5,4 @@ const b1 = d1; console.log('a.js'); export { b1 as b }; console.log('entry'); +const b2 = b1; diff --git a/spack/tests/pass/reexport/recursive-step1/output/entry.js b/spack/tests/pass/reexport/recursive-step1/output/entry.js index 5ce34391b83a..b5188b029bca 100644 --- a/spack/tests/pass/reexport/recursive-step1/output/entry.js +++ b/spack/tests/pass/reexport/recursive-step1/output/entry.js @@ -1,10 +1,12 @@ +console.log('b'); const c = 'c'; console.log('c'); -console.log('b'); const c1 = c; const b2 = c1; const __default = b2; -const b1 = __default; +const __default1 = __default; +const b1 = __default1; console.log('a.js'); export { b1 as b }; console.log('entry'); +const b3 = b1; diff --git a/spack/tests/pass/reexport/recursive-step2/output/entry.js b/spack/tests/pass/reexport/recursive-step2/output/entry.js index d8157275c16c..8fbbbd944776 100644 --- a/spack/tests/pass/reexport/recursive-step2/output/entry.js +++ b/spack/tests/pass/reexport/recursive-step2/output/entry.js @@ -1,12 +1,14 @@ +console.log('b'); const d = 1; const d1 = d; console.log('d'); console.log('c'); -console.log('b'); const c = d1; const b2 = c; const __default = b2; -const b1 = __default; +const __default1 = __default; +const b1 = __default1; console.log('a.js'); export { b1 as b }; console.log('entry'); +const b3 = b1; diff --git a/spack/tests/pass/reexport/recursive/output/entry.js b/spack/tests/pass/reexport/recursive/output/entry.js index 41f99e93dc42..76d6d43582a2 100644 --- a/spack/tests/pass/reexport/recursive/output/entry.js +++ b/spack/tests/pass/reexport/recursive/output/entry.js @@ -1,3 +1,4 @@ +console.log('b'); const e = 'e'; console.log('e'); const e1 = e; @@ -5,11 +6,12 @@ const d = e1; const d1 = d; console.log('d'); console.log('c'); -console.log('b'); const c = d1; const b2 = c; const __default = b2; -const b1 = __default; +const __default1 = __default; +const b1 = __default1; console.log('a.js'); export { b1 as b }; console.log('entry'); +const b3 = b1; diff --git a/spack/tests/pass/swcrc/jsx/issue-884/output/entry.js b/spack/tests/pass/swcrc/jsx/issue-884/output/entry.js index 8d6f3a249d3f..25de79770790 100644 --- a/spack/tests/pass/swcrc/jsx/issue-884/output/entry.js +++ b/spack/tests/pass/swcrc/jsx/issue-884/output/entry.js @@ -1,3 +1,5 @@ +var Divider = React.createElement("div", null); +const Divider1 = Divider; /** * Don't ask why it is named as divider. - */ export var Divider = React.createElement("div", null); + */ export { Divider as Divider }; diff --git a/spack/tests/pass/transitive/export-all-1/output/entry.js b/spack/tests/pass/transitive/export-all-1/output/entry.js index cb685e004ebd..ef914c60d791 100644 --- a/spack/tests/pass/transitive/export-all-1/output/entry.js +++ b/spack/tests/pass/transitive/export-all-1/output/entry.js @@ -1,10 +1,15 @@ -const c2 = 3; -const c1 = c2; +const e = 5; +const b = 1; +const e1 = e; +const e2 = e1; +export { e1 as e }; +const d = 4; +const c = 3; +const c1 = c; +const c2 = c1; export { c1 as c }; -const d2 = 4; -const d1 = d2; +const d1 = d; +const d2 = d1; export { d1 as d }; -export const b = 1; -const e2 = 5; -const e1 = e2; -export { e1 as e }; +const b1 = b; +export { b as b }; diff --git a/spack/tests/pass/transitive/export-all-2/output/entry.js b/spack/tests/pass/transitive/export-all-2/output/entry.js index cfc6b271b76d..f365c2ef254d 100644 --- a/spack/tests/pass/transitive/export-all-2/output/entry.js +++ b/spack/tests/pass/transitive/export-all-2/output/entry.js @@ -1,10 +1,15 @@ -const c2 = 3; -const c1 = c2; -export { c1 as d }; -const d = 4; -const d1 = d; -export { d1 as c }; -export const b = 1; const e = 5; +const b = 1; const e1 = e; +const a = e1; export { e1 as a }; +const d = 4; +const c = 3; +const c1 = c; +const d1 = c1; +export { c1 as d }; +const d2 = d; +const c2 = d2; +export { d2 as c }; +const b1 = b; +export { b as b }; diff --git a/spack/tests/pass/transitive/export-named/output/entry.js b/spack/tests/pass/transitive/export-named/output/entry.js index 04ccdb0b6e71..bcc668ed28c7 100644 --- a/spack/tests/pass/transitive/export-named/output/entry.js +++ b/spack/tests/pass/transitive/export-named/output/entry.js @@ -2,7 +2,10 @@ const foo3 = 1; const bar3 = 1; const baz3 = 1; const foo1 = foo3, bar1 = bar3, baz1 = baz3; +const baz2 = baz1; const foo2 = foo1, bar2 = bar1; export { foo2 as foo, bar2 as bar }; -const baz2 = baz1; export { baz2 as baz }; +const foo4 = foo2; +const bar4 = bar2; +const baz4 = baz2; diff --git a/spack/tests/pass/transitive/import/simple-2/output/entry.js b/spack/tests/pass/transitive/import/simple-2/output/entry.js index e9b6d708a218..779d6650d13a 100644 --- a/spack/tests/pass/transitive/import/simple-2/output/entry.js +++ b/spack/tests/pass/transitive/import/simple-2/output/entry.js @@ -1,18 +1,18 @@ +const common = 2; const common1 = 1; +const common3 = 3; const common11 = common1; const common12 = common11; -const common3 = 3; -const common31 = common3; -const common32 = common31; const common13 = common11; -const common = 2; const common2 = common; const common21 = common2; -var common4; const common22 = common2; console.log('a', common13, common22); +const common31 = common3; +const common32 = common31; const common33 = common31; console.log('b', common33, common12); +var common4; try { common4 = 4; } catch (e) { diff --git a/spack/tests/pass/tree-shaking/in-module-export/output/entry.js b/spack/tests/pass/tree-shaking/in-module-export/output/entry.js index ba388076b144..eb9458adb3c0 100644 --- a/spack/tests/pass/tree-shaking/in-module-export/output/entry.js +++ b/spack/tests/pass/tree-shaking/in-module-export/output/entry.js @@ -1,2 +1,4 @@ const b = 1; -export const foo = b; +const foo = b; +const foo1 = foo; +export { foo as foo };