summaryrefslogtreecommitdiff
path: root/cli/program_state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/program_state.rs')
-rw-r--r--cli/program_state.rs136
1 files changed, 69 insertions, 67 deletions
diff --git a/cli/program_state.rs b/cli/program_state.rs
index 223d043ba..008244b5f 100644
--- a/cli/program_state.rs
+++ b/cli/program_state.rs
@@ -8,7 +8,6 @@ use crate::http_cache;
use crate::http_util;
use crate::import_map::ImportMap;
use crate::lockfile::Lockfile;
-use crate::media_type::MediaType;
use crate::module_graph::CheckOptions;
use crate::module_graph::GraphBuilder;
use crate::module_graph::TranspileOptions;
@@ -18,11 +17,14 @@ use crate::specifier_handler::FetchHandler;
use deno_runtime::inspector::InspectorServer;
use deno_runtime::permissions::Permissions;
-use deno_core::error::generic_error;
+use deno_core::error::anyhow;
+use deno_core::error::get_custom_error_class;
use deno_core::error::AnyError;
use deno_core::url::Url;
+use deno_core::ModuleSource;
use deno_core::ModuleSpecifier;
use std::cell::RefCell;
+use std::collections::HashMap;
use std::env;
use std::rc::Rc;
use std::sync::Arc;
@@ -36,12 +38,6 @@ pub fn exit_unstable(api_name: &str) {
std::process::exit(70);
}
-// TODO(@kitsonk) probably can refactor this better with the graph.
-pub struct CompiledModule {
- pub code: String,
- pub name: String,
-}
-
/// This structure represents state of single "deno" program.
///
/// It is shared by all created workers (thus V8 isolates).
@@ -50,6 +46,8 @@ pub struct ProgramState {
pub flags: flags::Flags,
pub dir: deno_dir::DenoDir,
pub file_fetcher: FileFetcher,
+ pub modules:
+ Arc<Mutex<HashMap<ModuleSpecifier, Result<ModuleSource, AnyError>>>>,
pub lockfile: Option<Arc<Mutex<Lockfile>>>,
pub maybe_import_map: Option<ImportMap>,
pub maybe_inspector_server: Option<Arc<InspectorServer>>,
@@ -111,6 +109,7 @@ impl ProgramState {
dir,
flags,
file_fetcher,
+ modules: Default::default(),
lockfile,
maybe_import_map,
maybe_inspector_server,
@@ -146,17 +145,17 @@ impl ProgramState {
let debug = self.flags.log_level == Some(log::Level::Debug);
let maybe_config_path = self.flags.config_path.clone();
- if self.flags.no_check {
- let (stats, maybe_ignored_options) =
- graph.transpile(TranspileOptions {
- debug,
- maybe_config_path,
- reload: self.flags.reload,
- })?;
- debug!("{}", stats);
- if let Some(ignored_options) = maybe_ignored_options {
- eprintln!("{}", ignored_options);
+ let result_modules = if self.flags.no_check {
+ let result_info = graph.transpile(TranspileOptions {
+ debug,
+ maybe_config_path,
+ reload: self.flags.reload,
+ })?;
+ debug!("{}", result_info.stats);
+ if let Some(ignored_options) = result_info.maybe_ignored_options {
+ warn!("{}", ignored_options);
}
+ result_info.loadable_modules
} else {
let result_info = graph.check(CheckOptions {
debug,
@@ -171,10 +170,14 @@ impl ProgramState {
eprintln!("{}", ignored_options);
}
if !result_info.diagnostics.is_empty() {
- return Err(generic_error(result_info.diagnostics.to_string()));
+ return Err(anyhow!(result_info.diagnostics));
}
+ result_info.loadable_modules
};
+ let mut loadable_modules = self.modules.lock().unwrap();
+ loadable_modules.extend(result_modules);
+
if let Some(ref lockfile) = self.lockfile {
let g = lockfile.lock().unwrap();
g.write()?;
@@ -183,56 +186,55 @@ impl ProgramState {
Ok(())
}
- pub fn fetch_compiled_module(
+ pub fn load(
&self,
- module_specifier: ModuleSpecifier,
+ specifier: ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
- ) -> Result<CompiledModule, AnyError> {
- // TODO(@kitsonk) this really needs to be avoided and refactored out, as we
- // really should just be getting this from the module graph.
- let out = self
- .file_fetcher
- .get_source(&module_specifier)
- .expect("Cached source file doesn't exist");
-
- let specifier = out.specifier.clone();
- let compiled_module = if let Some((code, _)) =
- self.get_emit(&specifier.as_url())
- {
- CompiledModule {
- code: String::from_utf8(code).unwrap(),
- name: specifier.as_url().to_string(),
- }
- // We expect a compiled source for any non-JavaScript files, except for
- // local files that have an unknown media type and no referrer (root modules
- // that do not have an extension.)
- } else if out.media_type != MediaType::JavaScript
- && !(out.media_type == MediaType::Unknown
- && maybe_referrer.is_none()
- && specifier.as_url().scheme() == "file")
- {
- let message = if let Some(referrer) = maybe_referrer {
- format!("Compiled module not found \"{}\"\n From: {}\n If the source module contains only types, use `import type` and `export type` to import it instead.", module_specifier, referrer)
- } else {
- format!("Compiled module not found \"{}\"\n If the source module contains only types, use `import type` and `export type` to import it instead.", module_specifier)
- };
- info!("{}: {}", crate::colors::yellow("warning"), message);
- CompiledModule {
- code: "".to_string(),
- name: specifier.as_url().to_string(),
- }
- } else {
- CompiledModule {
- code: out.source,
- name: specifier.as_url().to_string(),
- }
- };
-
- Ok(compiled_module)
+ ) -> Result<ModuleSource, AnyError> {
+ let modules = self.modules.lock().unwrap();
+ modules
+ .get(&specifier)
+ .map(|r| match r {
+ Ok(module_source) => Ok(module_source.clone()),
+ Err(err) => {
+ // TODO(@kitsonk) this feels a bit hacky but it works, without
+ // introducing another enum to have to try to deal with.
+ if get_custom_error_class(err) == Some("NotFound") {
+ let message = if let Some(referrer) = &maybe_referrer {
+ format!("{}\n From: {}\n If the source module contains only types, use `import type` and `export type` to import it instead.", err, referrer)
+ } else {
+ format!("{}\n If the source module contains only types, use `import type` and `export type` to import it instead.", err)
+ };
+ warn!("{}: {}", crate::colors::yellow("warning"), message);
+ Ok(ModuleSource {
+ code: "".to_string(),
+ module_url_found: specifier.to_string(),
+ module_url_specified: specifier.to_string(),
+ })
+ } else {
+ // anyhow errors don't support cloning, so we have to manage this
+ // ourselves
+ Err(anyhow!(err.to_string()))
+ }
+ },
+ })
+ .unwrap_or_else(|| {
+ if let Some(referrer) = maybe_referrer {
+ Err(anyhow!(
+ "Module \"{}\" is missing from the graph.\n From: {}",
+ specifier,
+ referrer
+ ))
+ } else {
+ Err(anyhow!(
+ "Module \"{}\" is missing from the graph.",
+ specifier
+ ))
+ }
+ })
}
- // TODO(@kitsonk) this should be a straight forward API on file_fetcher or
- // whatever future refactors do...
+ // TODO(@kitsonk) this should be refactored to get it from the module graph
fn get_emit(&self, url: &Url) -> Option<(Vec<u8>, Option<Vec<u8>>)> {
match url.scheme() {
// we should only be looking for emits for schemes that denote external
@@ -245,11 +247,11 @@ impl ProgramState {
let emit_path = self
.dir
.gen_cache
- .get_cache_filename_with_extension(&url, "js");
+ .get_cache_filename_with_extension(&url, "js")?;
let emit_map_path = self
.dir
.gen_cache
- .get_cache_filename_with_extension(&url, "js.map");
+ .get_cache_filename_with_extension(&url, "js.map")?;
if let Ok(code) = self.dir.gen_cache.get(&emit_path) {
let maybe_map = if let Ok(map) = self.dir.gen_cache.get(&emit_map_path) {
Some(map)