diff options
Diffstat (limited to 'cli/module_loader.rs')
-rw-r--r-- | cli/module_loader.rs | 222 |
1 files changed, 125 insertions, 97 deletions
diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 7de45af28..d8a5b73c4 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -20,6 +20,7 @@ use crate::tools::check::TypeChecker; use crate::util::progress_bar::ProgressBar; use crate::util::text_encoding::code_without_source_map; use crate::util::text_encoding::source_map_from_code; +use crate::worker::ModuleLoaderFactory; use deno_ast::MediaType; use deno_core::anyhow::anyhow; @@ -223,21 +224,98 @@ pub struct ModuleCodeSource { pub media_type: MediaType, } +struct PreparedModuleLoader { + emitter: Arc<Emitter>, + graph_container: Arc<ModuleGraphContainer>, + parsed_source_cache: Arc<ParsedSourceCache>, +} + +impl PreparedModuleLoader { + pub fn load_prepared_module( + &self, + specifier: &ModuleSpecifier, + maybe_referrer: Option<&ModuleSpecifier>, + ) -> Result<ModuleCodeSource, AnyError> { + if specifier.scheme() == "node" { + unreachable!(); // Node built-in modules should be handled internally. + } + + let graph = self.graph_container.graph(); + match graph.get(specifier) { + Some(deno_graph::Module::Json(JsonModule { + source, + media_type, + specifier, + .. + })) => Ok(ModuleCodeSource { + code: source.clone().into(), + found_url: specifier.clone(), + media_type: *media_type, + }), + Some(deno_graph::Module::Esm(EsmModule { + source, + media_type, + specifier, + .. + })) => { + let code: ModuleCode = match media_type { + MediaType::JavaScript + | MediaType::Unknown + | MediaType::Cjs + | MediaType::Mjs + | MediaType::Json => source.clone().into(), + MediaType::Dts | MediaType::Dcts | MediaType::Dmts => { + Default::default() + } + MediaType::TypeScript + | MediaType::Mts + | MediaType::Cts + | MediaType::Jsx + | MediaType::Tsx => { + // get emit text + self + .emitter + .emit_parsed_source(specifier, *media_type, source)? + } + MediaType::TsBuildInfo | MediaType::Wasm | MediaType::SourceMap => { + panic!("Unexpected media type {media_type} for {specifier}") + } + }; + + // at this point, we no longer need the parsed source in memory, so free it + self.parsed_source_cache.free(specifier); + + Ok(ModuleCodeSource { + code, + found_url: specifier.clone(), + media_type: *media_type, + }) + } + _ => { + let mut msg = format!("Loading unprepared module: {specifier}"); + if let Some(referrer) = maybe_referrer { + msg = format!("{}, imported from: {}", msg, referrer.as_str()); + } + Err(anyhow!(msg)) + } + } + } +} + struct SharedCliModuleLoaderState { lib_window: TsTypeLib, lib_worker: TsTypeLib, is_inspecting: bool, is_repl: bool, - emitter: Arc<Emitter>, graph_container: Arc<ModuleGraphContainer>, module_load_preparer: Arc<ModuleLoadPreparer>, - parsed_source_cache: Arc<ParsedSourceCache>, + prepared_module_loader: PreparedModuleLoader, resolver: Arc<CliGraphResolver>, npm_module_loader: NpmModuleLoader, } pub struct CliModuleLoaderFactory { - state: Arc<SharedCliModuleLoaderState>, + shared: Arc<SharedCliModuleLoaderState>, } impl CliModuleLoaderFactory { @@ -251,61 +329,72 @@ impl CliModuleLoaderFactory { npm_module_loader: NpmModuleLoader, ) -> Self { Self { - state: Arc::new(SharedCliModuleLoaderState { + shared: Arc::new(SharedCliModuleLoaderState { lib_window: options.ts_type_lib_window(), lib_worker: options.ts_type_lib_worker(), is_inspecting: options.is_inspecting(), is_repl: matches!(options.sub_command(), DenoSubcommand::Repl(_)), - emitter, + prepared_module_loader: PreparedModuleLoader { + emitter, + graph_container: graph_container.clone(), + parsed_source_cache, + }, graph_container, module_load_preparer, - parsed_source_cache, resolver, npm_module_loader, }), } } - pub fn create_for_main( + fn create_with_lib( &self, + lib: TsTypeLib, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { - self.create_with_lib( - self.state.lib_window, + ) -> Rc<dyn ModuleLoader> { + Rc::new(CliModuleLoader { + lib, root_permissions, dynamic_permissions, - ) + shared: self.shared.clone(), + }) } +} - pub fn create_for_worker( +impl ModuleLoaderFactory for CliModuleLoaderFactory { + fn create_for_main( &self, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { + ) -> Rc<dyn ModuleLoader> { self.create_with_lib( - self.state.lib_worker, + self.shared.lib_window, root_permissions, dynamic_permissions, ) } - fn create_with_lib( + fn create_for_worker( &self, - lib: TsTypeLib, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { - CliModuleLoader { - lib, + ) -> Rc<dyn ModuleLoader> { + self.create_with_lib( + self.shared.lib_worker, root_permissions, dynamic_permissions, - shared: self.state.clone(), - } + ) + } + + fn create_source_map_getter(&self) -> Option<Box<dyn SourceMapGetter>> { + Some(Box::new(CliSourceMapGetter { + shared: self.shared.clone(), + })) } } -pub struct CliModuleLoader { +struct CliModuleLoader { lib: TsTypeLib, /// The initial set of permissions used to resolve the static imports in the /// worker. These are "allow all" for main worker, and parent thread @@ -318,78 +407,6 @@ pub struct CliModuleLoader { } impl CliModuleLoader { - fn load_prepared_module( - &self, - specifier: &ModuleSpecifier, - maybe_referrer: Option<&ModuleSpecifier>, - ) -> Result<ModuleCodeSource, AnyError> { - if specifier.scheme() == "node" { - unreachable!(); // Node built-in modules should be handled internally. - } - - let graph = self.shared.graph_container.graph(); - match graph.get(specifier) { - Some(deno_graph::Module::Json(JsonModule { - source, - media_type, - specifier, - .. - })) => Ok(ModuleCodeSource { - code: source.clone().into(), - found_url: specifier.clone(), - media_type: *media_type, - }), - Some(deno_graph::Module::Esm(EsmModule { - source, - media_type, - specifier, - .. - })) => { - let code: ModuleCode = match media_type { - MediaType::JavaScript - | MediaType::Unknown - | MediaType::Cjs - | MediaType::Mjs - | MediaType::Json => source.clone().into(), - MediaType::Dts | MediaType::Dcts | MediaType::Dmts => { - Default::default() - } - MediaType::TypeScript - | MediaType::Mts - | MediaType::Cts - | MediaType::Jsx - | MediaType::Tsx => { - // get emit text - self.shared.emitter.emit_parsed_source( - specifier, - *media_type, - source, - )? - } - MediaType::TsBuildInfo | MediaType::Wasm | MediaType::SourceMap => { - panic!("Unexpected media type {media_type} for {specifier}") - } - }; - - // at this point, we no longer need the parsed source in memory, so free it - self.shared.parsed_source_cache.free(specifier); - - Ok(ModuleCodeSource { - code, - found_url: specifier.clone(), - media_type: *media_type, - }) - } - _ => { - let mut msg = format!("Loading unprepared module: {specifier}"); - if let Some(referrer) = maybe_referrer { - msg = format!("{}, imported from: {}", msg, referrer.as_str()); - } - Err(anyhow!(msg)) - } - } - } - fn load_sync( &self, specifier: &ModuleSpecifier, @@ -409,7 +426,10 @@ impl CliModuleLoader { )? { code_source } else { - self.load_prepared_module(specifier, maybe_referrer)? + self + .shared + .prepared_module_loader + .load_prepared_module(specifier, maybe_referrer)? }; let code = if self.shared.is_inspecting { // we need the code with the source map in order for @@ -584,7 +604,11 @@ impl ModuleLoader for CliModuleLoader { } } -impl SourceMapGetter for CliModuleLoader { +struct CliSourceMapGetter { + shared: Arc<SharedCliModuleLoaderState>, +} + +impl SourceMapGetter for CliSourceMapGetter { fn get_source_map(&self, file_name: &str) -> Option<Vec<u8>> { let specifier = resolve_url(file_name).ok()?; match specifier.scheme() { @@ -593,7 +617,11 @@ impl SourceMapGetter for CliModuleLoader { "wasm" | "file" | "http" | "https" | "data" | "blob" => (), _ => return None, } - let source = self.load_prepared_module(&specifier, None).ok()?; + let source = self + .shared + .prepared_module_loader + .load_prepared_module(&specifier, None) + .ok()?; source_map_from_code(&source.code) } |