summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/deno_dir.rs22
-rw-r--r--src/isolate.rs73
-rw-r--r--src/main.rs16
-rw-r--r--src/modules.rs183
4 files changed, 213 insertions, 81 deletions
diff --git a/src/deno_dir.rs b/src/deno_dir.rs
index a6a6d0b6c..b074c0458 100644
--- a/src/deno_dir.rs
+++ b/src/deno_dir.rs
@@ -447,28 +447,6 @@ impl DenoDir {
debug!("module_name: {}, filename: {}", module_name, filename);
Ok((module_name, filename))
}
-
- pub fn print_file_info(self: &Self, filename: String) {
- let maybe_out = self.code_fetch(&filename, ".");
- if maybe_out.is_err() {
- println!("{}", maybe_out.unwrap_err());
- return;
- }
- let out = maybe_out.unwrap();
-
- println!("local: {}", &(out.filename));
- println!("type: {}", msg::enum_name_media_type(out.media_type));
- if out.maybe_output_code_filename.is_some() {
- println!(
- "compiled: {}",
- out.maybe_output_code_filename.as_ref().unwrap(),
- );
- }
- if out.maybe_source_map_filename.is_some() {
- println!("map: {}", out.maybe_source_map_filename.as_ref().unwrap());
- }
- // TODO print deps.
- }
}
impl SourceMapGetter for DenoDir {
diff --git a/src/isolate.rs b/src/isolate.rs
index fbe65a54e..20733c876 100644
--- a/src/isolate.rs
+++ b/src/isolate.rs
@@ -14,17 +14,17 @@ use crate::errors::RustOrJsError;
use crate::flags;
use crate::js_errors::JSError;
use crate::libdeno;
+use crate::modules::Modules;
use crate::msg;
use crate::permissions::DenoPermissions;
use crate::tokio_util;
-
use futures::sync::mpsc as async_mpsc;
use futures::Future;
use libc::c_char;
use libc::c_void;
use std;
use std::cell::Cell;
-use std::collections::HashMap;
+use std::cell::RefCell;
use std::env;
use std::ffi::CStr;
use std::ffi::CString;
@@ -52,10 +52,6 @@ pub type Dispatch =
fn(isolate: &Isolate, buf: libdeno::deno_buf, data_buf: libdeno::deno_buf)
-> (bool, Box<Op>);
-pub struct ModuleInfo {
- name: String,
-}
-
pub struct Isolate {
libdeno_isolate: *const libdeno::isolate,
dispatch: Dispatch,
@@ -63,8 +59,7 @@ pub struct Isolate {
tx: mpsc::Sender<(i32, Buf)>,
ntasks: Cell<i32>,
timeout_due: Cell<Option<Instant>>,
- pub modules: HashMap<libdeno::deno_mod, ModuleInfo>,
- pub modules_by_name: HashMap<String, libdeno::deno_mod>,
+ pub modules: RefCell<Modules>,
pub state: Arc<IsolateState>,
}
@@ -202,8 +197,7 @@ impl Isolate {
tx,
ntasks: Cell::new(0),
timeout_due: Cell::new(None),
- modules: HashMap::new(),
- modules_by_name: HashMap::new(),
+ modules: RefCell::new(Modules::new()),
state,
}
}
@@ -290,49 +284,11 @@ impl Isolate {
return Err(js_error);
}
- let name2 = name.clone();
- self.modules.insert(id, ModuleInfo { name });
-
- debug!("modules_by_name insert {}", name2);
- self.modules_by_name.insert(name2, id);
+ self.modules.borrow_mut().register(id, &name);
Ok(id)
}
- // TODO(ry) This should be private...
- pub fn resolve_cb(
- &self,
- specifier: &str,
- referrer: libdeno::deno_mod,
- ) -> libdeno::deno_mod {
- self
- .state
- .metrics
- .resolve_count
- .fetch_add(1, Ordering::Relaxed);
-
- debug!("resolve_cb {}", specifier);
-
- let r = self.modules.get(&referrer);
- if r.is_none() {
- debug!("cant find referrer {}", referrer);
- return 0;
- }
- let referrer_name = &r.unwrap().name;
- let r = self.state.dir.resolve_module(specifier, referrer_name);
- if let Err(err) = r {
- debug!("potentially swallowed err: {}", err);
- return 0;
- }
- let (name, _local_filename) = r.unwrap();
-
- if let Some(id) = self.modules_by_name.get(&name) {
- return *id;
- } else {
- return 0;
- }
- }
-
// TODO(ry) make this return a future.
pub fn mod_load_deps(
&mut self,
@@ -340,8 +296,8 @@ impl Isolate {
) -> Result<(), RustOrJsError> {
// basically iterate over the imports, start loading them.
- let referrer = &self.modules[&id];
- let referrer_name = referrer.name.clone();
+ let referrer_name =
+ { self.modules.borrow_mut().get_name(id).unwrap().clone() };
let len =
unsafe { libdeno::deno_mod_imports_len(self.libdeno_isolate, id) };
@@ -366,7 +322,7 @@ impl Isolate {
debug!("mod_load_deps {} {}", i, name);
- if None == self.modules_by_name.get(&name) {
+ if !self.modules.borrow_mut().is_registered(&name) {
let out =
code_fetch_and_maybe_compile(&self.state, specifier, &referrer_name)?;
let child_id =
@@ -415,7 +371,7 @@ impl Isolate {
.map_err(RustOrJsError::from)?;
let id = self
- .mod_new(out.filename.clone(), out.js_source())
+ .mod_new(out.module_name.clone(), out.js_source())
.map_err(RustOrJsError::from)?;
self.mod_load_deps(id)?;
@@ -539,7 +495,16 @@ extern "C" fn resolve_cb(
let isolate = unsafe { Isolate::from_raw_ptr(user_data) };
let specifier_c: &CStr = unsafe { CStr::from_ptr(specifier_ptr) };
let specifier: &str = specifier_c.to_str().unwrap();
- isolate.resolve_cb(specifier, referrer)
+ isolate
+ .state
+ .metrics
+ .resolve_count
+ .fetch_add(1, Ordering::Relaxed);
+ isolate.modules.borrow_mut().resolve_cb(
+ &isolate.state.dir,
+ specifier,
+ referrer,
+ )
}
// Dereferences the C pointer into the Rust Isolate object.
diff --git a/src/main.rs b/src/main.rs
index 25e68e344..d3ec4b721 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,7 @@ mod http_util;
pub mod isolate;
pub mod js_errors;
pub mod libdeno;
+pub mod modules;
pub mod msg;
pub mod msg_util;
pub mod ops;
@@ -90,7 +91,7 @@ fn main() {
flags.allow_write = true;
}
- let should_prefetch = flags.prefetch;
+ let should_prefetch = flags.prefetch || flags.info;
let should_display_info = flags.info;
let state = Arc::new(isolate::IsolateState::new(flags, rest_argv, None));
@@ -107,14 +108,19 @@ fn main() {
// Execute input file.
if isolate.state.argv.len() > 1 {
let input_filename = isolate.state.argv[1].clone();
+ isolate
+ .execute_mod(&input_filename, should_prefetch)
+ .unwrap_or_else(print_err_and_exit);
+
if should_display_info {
// Display file info and exit. Do not run file
- isolate.state.dir.print_file_info(input_filename);
+ modules::print_file_info(
+ &isolate.modules.borrow(),
+ &isolate.state.dir,
+ input_filename,
+ );
std::process::exit(0);
}
- isolate
- .execute_mod(&input_filename, should_prefetch)
- .unwrap_or_else(print_err_and_exit);
}
isolate
diff --git a/src/modules.rs b/src/modules.rs
new file mode 100644
index 000000000..7711dec95
--- /dev/null
+++ b/src/modules.rs
@@ -0,0 +1,183 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use crate::ansi;
+use crate::deno_dir::DenoDir;
+use crate::libdeno::deno_mod;
+use crate::msg;
+use std::collections::HashMap;
+use std::collections::HashSet;
+use std::fmt;
+
+pub struct ModuleInfo {
+ name: String,
+ children: Vec<deno_mod>,
+}
+
+/// A collection of JS modules.
+#[derive(Default)]
+pub struct Modules {
+ pub info: HashMap<deno_mod, ModuleInfo>,
+ pub by_name: HashMap<String, deno_mod>,
+}
+
+impl Modules {
+ pub fn new() -> Modules {
+ Self {
+ info: HashMap::new(),
+ by_name: HashMap::new(),
+ }
+ }
+
+ pub fn get_id(&self, name: &str) -> Option<deno_mod> {
+ self.by_name.get(name).cloned()
+ }
+
+ pub fn get_children(&self, id: deno_mod) -> Option<&Vec<deno_mod>> {
+ self.info.get(&id).map(|i| &i.children)
+ }
+
+ pub fn get_name(&self, id: deno_mod) -> Option<&String> {
+ self.info.get(&id).map(|i| &i.name)
+ }
+
+ pub fn is_registered(&self, name: &str) -> bool {
+ self.by_name.get(name).is_some()
+ }
+
+ pub fn register(&mut self, id: deno_mod, name: &str) {
+ let name = String::from(name);
+ debug!("register {}", name);
+ self.by_name.insert(name.clone(), id);
+ self.info.insert(
+ id,
+ ModuleInfo {
+ name,
+ children: Vec::new(),
+ },
+ );
+ }
+
+ pub fn resolve_cb(
+ &mut self,
+ deno_dir: &DenoDir,
+ specifier: &str,
+ referrer: deno_mod,
+ ) -> deno_mod {
+ debug!("resolve_cb {}", specifier);
+
+ let maybe_info = self.info.get_mut(&referrer);
+ if maybe_info.is_none() {
+ debug!("cant find referrer {}", referrer);
+ return 0;
+ }
+ let info = maybe_info.unwrap();
+ let referrer_name = &info.name;
+ let r = deno_dir.resolve_module(specifier, referrer_name);
+ if let Err(err) = r {
+ debug!("potentially swallowed err: {}", err);
+ return 0;
+ }
+ let (name, _local_filename) = r.unwrap();
+
+ if let Some(id) = self.by_name.get(&name) {
+ let child_id = *id;
+ info.children.push(child_id);
+ return child_id;
+ } else {
+ return 0;
+ }
+ }
+}
+
+pub struct Deps {
+ pub name: String,
+ pub deps: Option<Vec<Deps>>,
+ depth: usize,
+}
+
+impl Deps {
+ pub fn new(modules: &Modules, module_name: &str) -> Deps {
+ let mut seen = HashSet::new();
+ let id = modules.get_id(module_name).unwrap();
+ Self::helper(&mut seen, 0, modules, id)
+ }
+
+ fn helper(
+ seen: &mut HashSet<deno_mod>,
+ depth: usize,
+ modules: &Modules,
+ id: deno_mod,
+ ) -> Deps {
+ let name = modules.get_name(id).unwrap().to_string();
+ if seen.contains(&id) {
+ Deps {
+ name,
+ depth,
+ deps: None,
+ }
+ } else {
+ seen.insert(id);
+ let child_ids = modules.get_children(id).unwrap();
+ let deps = child_ids
+ .iter()
+ .map(|dep_id| Self::helper(seen, depth + 1, modules, *dep_id))
+ .collect();
+ Deps {
+ name,
+ depth,
+ deps: Some(deps),
+ }
+ }
+ }
+}
+
+impl fmt::Display for Deps {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ for _i in 0..self.depth {
+ write!(f, "| ")?;
+ }
+ write!(f, "{}", self.name)?;
+ if let Some(ref deps) = self.deps {
+ for d in deps {
+ write!(f, "\n{}", d)?;
+ }
+ }
+ Ok(())
+ }
+}
+
+pub fn print_file_info(
+ modules: &Modules,
+ deno_dir: &DenoDir,
+ filename: String,
+) {
+ let maybe_out = deno_dir.code_fetch(&filename, ".");
+ if maybe_out.is_err() {
+ println!("{}", maybe_out.unwrap_err());
+ return;
+ }
+ let out = maybe_out.unwrap();
+
+ println!("{} {}", ansi::bold("local:".to_string()), &(out.filename));
+ println!(
+ "{} {}",
+ ansi::bold("type:".to_string()),
+ msg::enum_name_media_type(out.media_type)
+ );
+ if out.maybe_output_code_filename.is_some() {
+ println!(
+ "{} {}",
+ ansi::bold("compiled:".to_string()),
+ out.maybe_output_code_filename.as_ref().unwrap(),
+ );
+ }
+ if out.maybe_source_map_filename.is_some() {
+ println!(
+ "{} {}",
+ ansi::bold("map:".to_string()),
+ out.maybe_source_map_filename.as_ref().unwrap()
+ );
+ }
+
+ let deps = Deps::new(modules, &out.module_name);
+ println!("{} {}", ansi::bold("deps:".to_string()), deps);
+}