1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00

refactor: Cleanup core/modules.rs (#13149)

This commit is contained in:
Bartek Iwańczuk 2021-12-21 15:53:46 +01:00 committed by GitHub
parent 907cef563e
commit aca41a472a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 178 additions and 202 deletions

View file

@ -6,7 +6,6 @@ use crate::proc_state::ProcState;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::future::FutureExt; use deno_core::futures::future::FutureExt;
use deno_core::futures::Future; use deno_core::futures::Future;
use deno_core::ModuleLoadId;
use deno_core::ModuleLoader; use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
@ -84,7 +83,6 @@ impl ModuleLoader for CliModuleLoader {
fn prepare_load( fn prepare_load(
&self, &self,
op_state: Rc<RefCell<OpState>>, op_state: Rc<RefCell<OpState>>,
_load_id: ModuleLoadId,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
_maybe_referrer: Option<String>, _maybe_referrer: Option<String>,
is_dynamic: bool, is_dynamic: bool,
@ -108,7 +106,6 @@ impl ModuleLoader for CliModuleLoader {
}; };
drop(state); drop(state);
// TODO(bartlomieju): `prepare_module_load` should take `load_id` param
async move { async move {
ps.prepare_module_load( ps.prepare_module_load(
vec![specifier], vec![specifier],

View file

@ -57,17 +57,11 @@ pub use crate::module_specifier::ModuleSpecifier;
pub use crate::module_specifier::DUMMY_SPECIFIER; pub use crate::module_specifier::DUMMY_SPECIFIER;
pub use crate::modules::FsModuleLoader; pub use crate::modules::FsModuleLoader;
pub use crate::modules::ModuleId; pub use crate::modules::ModuleId;
pub use crate::modules::ModuleLoadId;
pub use crate::modules::ModuleLoader; pub use crate::modules::ModuleLoader;
pub use crate::modules::ModuleSource; pub use crate::modules::ModuleSource;
pub use crate::modules::ModuleSourceFuture; pub use crate::modules::ModuleSourceFuture;
pub use crate::modules::ModuleType; pub use crate::modules::ModuleType;
pub use crate::modules::NoopModuleLoader; pub use crate::modules::NoopModuleLoader;
pub use crate::runtime::CompiledWasmModuleStore;
pub use crate::runtime::SharedArrayBufferStore;
// TODO(bartlomieju): this struct should be implementation
// detail nad not be public
pub use crate::modules::RecursiveModuleLoad;
pub use crate::normalize_path::normalize_path; pub use crate::normalize_path::normalize_path;
pub use crate::ops::serialize_op_result; pub use crate::ops::serialize_op_result;
pub use crate::ops::Op; pub use crate::ops::Op;
@ -91,10 +85,12 @@ pub use crate::resources::AsyncResult;
pub use crate::resources::Resource; pub use crate::resources::Resource;
pub use crate::resources::ResourceId; pub use crate::resources::ResourceId;
pub use crate::resources::ResourceTable; pub use crate::resources::ResourceTable;
pub use crate::runtime::CompiledWasmModuleStore;
pub use crate::runtime::GetErrorClassFn; pub use crate::runtime::GetErrorClassFn;
pub use crate::runtime::JsErrorCreateFn; pub use crate::runtime::JsErrorCreateFn;
pub use crate::runtime::JsRuntime; pub use crate::runtime::JsRuntime;
pub use crate::runtime::RuntimeOptions; pub use crate::runtime::RuntimeOptions;
pub use crate::runtime::SharedArrayBufferStore;
pub use crate::runtime::Snapshot; pub use crate::runtime::Snapshot;
// pub use crate::runtime_modules::include_js_files!; // pub use crate::runtime_modules::include_js_files!;
pub use crate::extensions::Extension; pub use crate::extensions::Extension;

View file

@ -26,12 +26,12 @@ use std::task::Context;
use std::task::Poll; use std::task::Poll;
pub type ModuleId = i32; pub type ModuleId = i32;
pub type ModuleLoadId = i32; pub(crate) type ModuleLoadId = i32;
pub const BOM_CHAR: char = '\u{FEFF}'; pub const BOM_CHAR: char = '\u{FEFF}';
/// Strips the byte order mark from the provided text if it exists. /// Strips the byte order mark from the provided text if it exists.
pub fn strip_bom(text: &str) -> &str { fn strip_bom(text: &str) -> &str {
if text.starts_with(BOM_CHAR) { if text.starts_with(BOM_CHAR) {
&text[BOM_CHAR.len_utf8()..] &text[BOM_CHAR.len_utf8()..]
} else { } else {
@ -198,7 +198,7 @@ pub struct ModuleSource {
pub module_url_found: String, pub module_url_found: String,
} }
pub type PrepareLoadFuture = pub(crate) type PrepareLoadFuture =
dyn Future<Output = (ModuleLoadId, Result<RecursiveModuleLoad, Error>)>; dyn Future<Output = (ModuleLoadId, Result<RecursiveModuleLoad, Error>)>;
pub type ModuleSourceFuture = dyn Future<Output = Result<ModuleSource, Error>>; pub type ModuleSourceFuture = dyn Future<Output = Result<ModuleSource, Error>>;
@ -242,7 +242,6 @@ pub trait ModuleLoader {
fn prepare_load( fn prepare_load(
&self, &self,
_op_state: Rc<RefCell<OpState>>, _op_state: Rc<RefCell<OpState>>,
_load_id: ModuleLoadId,
_module_specifier: &ModuleSpecifier, _module_specifier: &ModuleSpecifier,
_maybe_referrer: Option<String>, _maybe_referrer: Option<String>,
_is_dyn_import: bool, _is_dyn_import: bool,
@ -352,49 +351,51 @@ pub enum LoadState {
} }
/// This future is used to implement parallel async module loading. /// This future is used to implement parallel async module loading.
pub struct RecursiveModuleLoad { pub(crate) struct RecursiveModuleLoad {
init: LoadInit,
// TODO(bartlomieju): in future this value should
// be randomized
pub id: ModuleLoadId, pub id: ModuleLoadId,
pub root_module_id: Option<ModuleId>, pub root_module_id: Option<ModuleId>,
pub root_module_type: Option<ModuleType>, init: LoadInit,
pub state: LoadState, root_module_type: Option<ModuleType>,
pub module_map_rc: Rc<RefCell<ModuleMap>>, state: LoadState,
module_map_rc: Rc<RefCell<ModuleMap>>,
pending: FuturesUnordered<Pin<Box<ModuleLoadFuture>>>,
visited: HashSet<ModuleRequest>,
// These two fields are copied from `module_map_rc`, but they are cloned ahead // These two fields are copied from `module_map_rc`, but they are cloned ahead
// of time to avoid already-borrowed errors. // of time to avoid already-borrowed errors.
pub op_state: Rc<RefCell<OpState>>, op_state: Rc<RefCell<OpState>>,
pub loader: Rc<dyn ModuleLoader>, loader: Rc<dyn ModuleLoader>,
pub pending: FuturesUnordered<Pin<Box<ModuleLoadFuture>>>,
pub visited: HashSet<ModuleRequest>,
} }
impl RecursiveModuleLoad { impl RecursiveModuleLoad {
/// Starts a new parallel load of the given URL of the main module. /// Starts a new asynchronous load of the module graph for given specifier.
pub fn main(specifier: &str, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self { ///
/// The module corresponding for the given `specifier` will be marked as
// "the main module" (`import.meta.main` will return `true` for this module).
fn main(specifier: &str, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self {
Self::new(LoadInit::Main(specifier.to_string()), module_map_rc) Self::new(LoadInit::Main(specifier.to_string()), module_map_rc)
} }
pub fn side(specifier: &str, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self { /// Starts a new asynchronous load of the module graph for given specifier.
fn side(specifier: &str, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self {
Self::new(LoadInit::Side(specifier.to_string()), module_map_rc) Self::new(LoadInit::Side(specifier.to_string()), module_map_rc)
} }
pub fn dynamic_import( /// Starts a new asynchronous load of the module graph for given specifier
/// that was imported using `import()`.
fn dynamic_import(
specifier: &str, specifier: &str,
referrer: &str, referrer: &str,
module_type: ModuleType, module_type: ModuleType,
module_map_rc: Rc<RefCell<ModuleMap>>, module_map_rc: Rc<RefCell<ModuleMap>>,
) -> Self { ) -> Self {
let init = LoadInit::DynamicImport( Self::new(
specifier.to_string(), LoadInit::DynamicImport(
referrer.to_string(), specifier.to_string(),
module_type, referrer.to_string(),
); module_type,
Self::new(init, module_map_rc) ),
} module_map_rc,
)
pub fn is_dynamic_import(&self) -> bool {
matches!(self.init, LoadInit::DynamicImport(..))
} }
fn new(init: LoadInit, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self { fn new(init: LoadInit, module_map_rc: Rc<RefCell<ModuleMap>>) -> Self {
@ -422,6 +423,7 @@ impl RecursiveModuleLoad {
pending: FuturesUnordered::new(), pending: FuturesUnordered::new(),
visited: HashSet::new(), visited: HashSet::new(),
}; };
// FIXME(bartlomieju): this seems fishy
// Ignore the error here, let it be hit in `Stream::poll_next()`. // Ignore the error here, let it be hit in `Stream::poll_next()`.
if let Ok(root_specifier) = load.resolve_root() { if let Ok(root_specifier) = load.resolve_root() {
if let Some(module_id) = module_map_rc if let Some(module_id) = module_map_rc
@ -435,7 +437,7 @@ impl RecursiveModuleLoad {
load load
} }
pub fn resolve_root(&self) -> Result<ModuleSpecifier, Error> { fn resolve_root(&self) -> Result<ModuleSpecifier, Error> {
match self.init { match self.init {
LoadInit::Main(ref specifier) => { LoadInit::Main(ref specifier) => {
self.loader.resolve(specifier, ".", true) self.loader.resolve(specifier, ".", true)
@ -449,7 +451,7 @@ impl RecursiveModuleLoad {
} }
} }
pub async fn prepare(&self) -> Result<(), Error> { async fn prepare(&self) -> Result<(), Error> {
let op_state = self.op_state.clone(); let op_state = self.op_state.clone();
let (module_specifier, maybe_referrer) = match self.init { let (module_specifier, maybe_referrer) = match self.init {
LoadInit::Main(ref specifier) => { LoadInit::Main(ref specifier) => {
@ -470,7 +472,6 @@ impl RecursiveModuleLoad {
.loader .loader
.prepare_load( .prepare_load(
op_state, op_state,
self.id,
&module_specifier, &module_specifier,
maybe_referrer, maybe_referrer,
self.is_dynamic_import(), self.is_dynamic_import(),
@ -478,13 +479,17 @@ impl RecursiveModuleLoad {
.await .await
} }
pub fn is_currently_loading_main_module(&self) -> bool { fn is_currently_loading_main_module(&self) -> bool {
!self.is_dynamic_import() !self.is_dynamic_import()
&& matches!(self.init, LoadInit::Main(..)) && matches!(self.init, LoadInit::Main(..))
&& self.state == LoadState::LoadingRoot && self.state == LoadState::LoadingRoot
} }
pub fn register_and_recurse( fn is_dynamic_import(&self) -> bool {
matches!(self.init, LoadInit::DynamicImport(..))
}
pub(crate) fn register_and_recurse(
&mut self, &mut self,
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
module_request: &ModuleRequest, module_request: &ModuleRequest,
@ -681,12 +686,13 @@ impl Stream for RecursiveModuleLoad {
/// it's `ModuleType::JavaScript`, but if there were import assertions /// it's `ModuleType::JavaScript`, but if there were import assertions
/// it might be `ModuleType::Json`. /// it might be `ModuleType::Json`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ModuleRequest { pub(crate) struct ModuleRequest {
pub specifier: ModuleSpecifier, pub specifier: ModuleSpecifier,
pub expected_module_type: ModuleType, pub expected_module_type: ModuleType,
} }
pub struct ModuleInfo { pub(crate) struct ModuleInfo {
#[allow(unused)]
pub id: ModuleId, pub id: ModuleId,
// Used in "bindings.rs" for "import.meta.main" property value. // Used in "bindings.rs" for "import.meta.main" property value.
pub main: bool, pub main: bool,
@ -706,7 +712,7 @@ enum SymbolicModule {
} }
/// A collection of JS modules. /// A collection of JS modules.
pub struct ModuleMap { pub(crate) struct ModuleMap {
// Handling of specifiers and v8 objects // Handling of specifiers and v8 objects
ids_by_handle: HashMap<v8::Global<v8::Module>, ModuleId>, ids_by_handle: HashMap<v8::Global<v8::Module>, ModuleId>,
handles_by_id: HashMap<ModuleId, v8::Global<v8::Module>>, handles_by_id: HashMap<ModuleId, v8::Global<v8::Module>>,
@ -731,7 +737,7 @@ pub struct ModuleMap {
} }
impl ModuleMap { impl ModuleMap {
pub fn new( pub(crate) fn new(
loader: Rc<dyn ModuleLoader>, loader: Rc<dyn ModuleLoader>,
op_state: Rc<RefCell<OpState>>, op_state: Rc<RefCell<OpState>>,
) -> ModuleMap { ) -> ModuleMap {
@ -753,11 +759,7 @@ impl ModuleMap {
/// Get module id, following all aliases in case of module specifier /// Get module id, following all aliases in case of module specifier
/// that had been redirected. /// that had been redirected.
pub fn get_id( fn get_id(&self, name: &str, module_type: ModuleType) -> Option<ModuleId> {
&self,
name: &str,
module_type: ModuleType,
) -> Option<ModuleId> {
let mut mod_name = name; let mut mod_name = name;
loop { loop {
let symbolic_module = let symbolic_module =
@ -805,24 +807,8 @@ impl ModuleMap {
let value_handle = v8::Global::<v8::Value>::new(tc_scope, parsed_json); let value_handle = v8::Global::<v8::Value>::new(tc_scope, parsed_json);
self.json_value_store.insert(handle.clone(), value_handle); self.json_value_store.insert(handle.clone(), value_handle);
let id = self.next_module_id; let id =
self.next_module_id += 1; self.create_module_info(name, ModuleType::Json, handle, false, vec![]);
self.by_name.insert(
(name.to_string(), ModuleType::Json),
SymbolicModule::Mod(id),
);
self.handles_by_id.insert(id, handle.clone());
self.ids_by_handle.insert(handle, id);
self.info.insert(
id,
ModuleInfo {
id,
main: false,
name: name.to_string(),
requests: vec![],
module_type: ModuleType::Json,
},
);
Ok(id) Ok(id)
} }
@ -902,12 +888,30 @@ impl ModuleMap {
} }
let handle = v8::Global::<v8::Module>::new(tc_scope, module); let handle = v8::Global::<v8::Module>::new(tc_scope, module);
let id = self.create_module_info(
name,
ModuleType::JavaScript,
handle,
main,
requests,
);
Ok(id)
}
fn create_module_info(
&mut self,
name: &str,
module_type: ModuleType,
handle: v8::Global<v8::Module>,
main: bool,
requests: Vec<ModuleRequest>,
) -> ModuleId {
let id = self.next_module_id; let id = self.next_module_id;
self.next_module_id += 1; self.next_module_id += 1;
self.by_name.insert( self
(name.to_string(), ModuleType::JavaScript), .by_name
SymbolicModule::Mod(id), .insert((name.to_string(), module_type), SymbolicModule::Mod(id));
);
self.handles_by_id.insert(id, handle.clone()); self.handles_by_id.insert(id, handle.clone());
self.ids_by_handle.insert(handle, id); self.ids_by_handle.insert(handle, id);
self.info.insert( self.info.insert(
@ -917,21 +921,18 @@ impl ModuleMap {
main, main,
name: name.to_string(), name: name.to_string(),
requests, requests,
module_type: ModuleType::JavaScript, module_type,
}, },
); );
Ok(id) id
} }
pub fn get_requested_modules( fn get_requested_modules(&self, id: ModuleId) -> Option<&Vec<ModuleRequest>> {
&self,
id: ModuleId,
) -> Option<&Vec<ModuleRequest>> {
self.info.get(&id).map(|i| &i.requests) self.info.get(&id).map(|i| &i.requests)
} }
pub fn is_registered( fn is_registered(
&self, &self,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
module_type: ModuleType, module_type: ModuleType,
@ -944,7 +945,7 @@ impl ModuleMap {
false false
} }
pub fn alias(&mut self, name: &str, module_type: ModuleType, target: &str) { fn alias(&mut self, name: &str, module_type: ModuleType, target: &str) {
self.by_name.insert( self.by_name.insert(
(name.to_string(), module_type), (name.to_string(), module_type),
SymbolicModule::Alias(target.to_string()), SymbolicModule::Alias(target.to_string()),
@ -952,16 +953,19 @@ impl ModuleMap {
} }
#[cfg(test)] #[cfg(test)]
pub fn is_alias(&self, name: &str, module_type: ModuleType) -> bool { fn is_alias(&self, name: &str, module_type: ModuleType) -> bool {
let cond = self.by_name.get(&(name.to_string(), module_type)); let cond = self.by_name.get(&(name.to_string(), module_type));
matches!(cond, Some(SymbolicModule::Alias(_))) matches!(cond, Some(SymbolicModule::Alias(_)))
} }
pub fn get_handle(&self, id: ModuleId) -> Option<v8::Global<v8::Module>> { pub(crate) fn get_handle(
&self,
id: ModuleId,
) -> Option<v8::Global<v8::Module>> {
self.handles_by_id.get(&id).cloned() self.handles_by_id.get(&id).cloned()
} }
pub fn get_info( pub(crate) fn get_info(
&self, &self,
global: &v8::Global<v8::Module>, global: &v8::Global<v8::Module>,
) -> Option<&ModuleInfo> { ) -> Option<&ModuleInfo> {
@ -972,11 +976,11 @@ impl ModuleMap {
None None
} }
pub fn get_info_by_id(&self, id: &ModuleId) -> Option<&ModuleInfo> { pub(crate) fn get_info_by_id(&self, id: &ModuleId) -> Option<&ModuleInfo> {
self.info.get(id) self.info.get(id)
} }
pub async fn load_main( pub(crate) async fn load_main(
module_map_rc: Rc<RefCell<ModuleMap>>, module_map_rc: Rc<RefCell<ModuleMap>>,
specifier: &str, specifier: &str,
) -> Result<RecursiveModuleLoad, Error> { ) -> Result<RecursiveModuleLoad, Error> {
@ -985,7 +989,7 @@ impl ModuleMap {
Ok(load) Ok(load)
} }
pub async fn load_side( pub(crate) async fn load_side(
module_map_rc: Rc<RefCell<ModuleMap>>, module_map_rc: Rc<RefCell<ModuleMap>>,
specifier: &str, specifier: &str,
) -> Result<RecursiveModuleLoad, Error> { ) -> Result<RecursiveModuleLoad, Error> {
@ -995,7 +999,7 @@ impl ModuleMap {
} }
// Initiate loading of a module graph imported using `import()`. // Initiate loading of a module graph imported using `import()`.
pub fn load_dynamic_import( pub(crate) fn load_dynamic_import(
module_map_rc: Rc<RefCell<ModuleMap>>, module_map_rc: Rc<RefCell<ModuleMap>>,
specifier: &str, specifier: &str,
referrer: &str, referrer: &str,
@ -1036,13 +1040,13 @@ impl ModuleMap {
.push(fut); .push(fut);
} }
pub fn has_pending_dynamic_imports(&self) -> bool { pub(crate) fn has_pending_dynamic_imports(&self) -> bool {
!(self.preparing_dynamic_imports.is_empty() !(self.preparing_dynamic_imports.is_empty()
&& self.pending_dynamic_imports.is_empty()) && self.pending_dynamic_imports.is_empty())
} }
/// Called by `module_resolve_callback` during module instantiation. /// Called by `module_resolve_callback` during module instantiation.
pub fn resolve_callback<'s>( pub(crate) fn resolve_callback<'s>(
&self, &self,
scope: &mut v8::HandleScope<'s>, scope: &mut v8::HandleScope<'s>,
specifier: &str, specifier: &str,
@ -1102,6 +1106,81 @@ mod tests {
} }
fn mock_source_code(url: &str) -> Option<(&'static str, &'static str)> { fn mock_source_code(url: &str) -> Option<(&'static str, &'static str)> {
const A_SRC: &str = r#"
import { b } from "/b.js";
import { c } from "/c.js";
if (b() != 'b') throw Error();
if (c() != 'c') throw Error();
if (!import.meta.main) throw Error();
if (import.meta.url != 'file:///a.js') throw Error();
"#;
const B_SRC: &str = r#"
import { c } from "/c.js";
if (c() != 'c') throw Error();
export function b() { return 'b'; }
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///b.js') throw Error();
"#;
const C_SRC: &str = r#"
import { d } from "/d.js";
export function c() { return 'c'; }
if (d() != 'd') throw Error();
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///c.js') throw Error();
"#;
const D_SRC: &str = r#"
export function d() { return 'd'; }
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///d.js') throw Error();
"#;
const CIRCULAR1_SRC: &str = r#"
import "/circular2.js";
Deno.core.print("circular1");
"#;
const CIRCULAR2_SRC: &str = r#"
import "/circular3.js";
Deno.core.print("circular2");
"#;
const CIRCULAR3_SRC: &str = r#"
import "/circular1.js";
import "/circular2.js";
Deno.core.print("circular3");
"#;
const REDIRECT1_SRC: &str = r#"
import "./redirect2.js";
Deno.core.print("redirect1");
"#;
const REDIRECT2_SRC: &str = r#"
import "./redirect3.js";
Deno.core.print("redirect2");
"#;
const REDIRECT3_SRC: &str = r#"Deno.core.print("redirect3");"#;
const MAIN_SRC: &str = r#"
// never_ready.js never loads.
import "/never_ready.js";
// slow.js resolves after one tick.
import "/slow.js";
"#;
const SLOW_SRC: &str = r#"
// Circular import of never_ready.js
// Does this trigger two ModuleLoader calls? It shouldn't.
import "/never_ready.js";
import "/a.js";
"#;
const BAD_IMPORT_SRC: &str = r#"import "foo";"#;
// (code, real_module_name) // (code, real_module_name)
let spec: Vec<&str> = url.split("file://").collect(); let spec: Vec<&str> = url.split("file://").collect();
match spec[1] { match spec[1] {
@ -1191,8 +1270,6 @@ mod tests {
referrer referrer
}; };
eprintln!(">> RESOLVING, S: {}, R: {}", specifier, referrer);
let output_specifier = match resolve_import(specifier, referrer) { let output_specifier = match resolve_import(specifier, referrer) {
Ok(specifier) => specifier, Ok(specifier) => specifier,
Err(..) => return Err(MockError::ResolveErr.into()), Err(..) => return Err(MockError::ResolveErr.into()),
@ -1218,37 +1295,6 @@ mod tests {
} }
} }
const A_SRC: &str = r#"
import { b } from "/b.js";
import { c } from "/c.js";
if (b() != 'b') throw Error();
if (c() != 'c') throw Error();
if (!import.meta.main) throw Error();
if (import.meta.url != 'file:///a.js') throw Error();
"#;
const B_SRC: &str = r#"
import { c } from "/c.js";
if (c() != 'c') throw Error();
export function b() { return 'b'; }
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///b.js') throw Error();
"#;
const C_SRC: &str = r#"
import { d } from "/d.js";
export function c() { return 'c'; }
if (d() != 'd') throw Error();
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///c.js') throw Error();
"#;
const D_SRC: &str = r#"
export function d() { return 'd'; }
if (import.meta.main) throw Error();
if (import.meta.url != 'file:///d.js') throw Error();
"#;
#[test] #[test]
fn test_recursive_load() { fn test_recursive_load() {
let loader = MockLoader::new(); let loader = MockLoader::new();
@ -1259,7 +1305,7 @@ mod tests {
}); });
let spec = resolve_url("file:///a.js").unwrap(); let spec = resolve_url("file:///a.js").unwrap();
let a_id_fut = runtime.load_main_module(&spec, None); let a_id_fut = runtime.load_main_module(&spec, None);
let a_id = futures::executor::block_on(a_id_fut).expect("Failed to load"); let a_id = futures::executor::block_on(a_id_fut).unwrap();
let _ = runtime.mod_evaluate(a_id); let _ = runtime.mod_evaluate(a_id);
futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); futures::executor::block_on(runtime.run_event_loop(false)).unwrap();
@ -1320,22 +1366,6 @@ mod tests {
assert_eq!(modules.get_requested_modules(d_id), Some(&vec![])); assert_eq!(modules.get_requested_modules(d_id), Some(&vec![]));
} }
const CIRCULAR1_SRC: &str = r#"
import "/circular2.js";
Deno.core.print("circular1");
"#;
const CIRCULAR2_SRC: &str = r#"
import "/circular3.js";
Deno.core.print("circular2");
"#;
const CIRCULAR3_SRC: &str = r#"
import "/circular1.js";
import "/circular2.js";
Deno.core.print("circular3");
"#;
#[test] #[test]
fn test_mods() { fn test_mods() {
#[derive(Default)] #[derive(Default)]
@ -1661,7 +1691,6 @@ mod tests {
fn prepare_load( fn prepare_load(
&self, &self,
_op_state: Rc<RefCell<OpState>>, _op_state: Rc<RefCell<OpState>>,
_load_id: ModuleLoadId,
_module_specifier: &ModuleSpecifier, _module_specifier: &ModuleSpecifier,
_maybe_referrer: Option<String>, _maybe_referrer: Option<String>,
_is_dyn_import: bool, _is_dyn_import: bool,
@ -1779,7 +1808,7 @@ mod tests {
fn load( fn load(
&self, &self,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>, _maybe_referrer: Option<ModuleSpecifier>,
_is_dyn_import: bool, _is_dyn_import: bool,
) -> Pin<Box<ModuleSourceFuture>> { ) -> Pin<Box<ModuleSourceFuture>> {
self.load_count.fetch_add(1, Ordering::Relaxed); self.load_count.fetch_add(1, Ordering::Relaxed);
@ -1788,7 +1817,6 @@ mod tests {
.unwrap() .unwrap()
.to_string_lossy() .to_string_lossy()
.to_string(); .to_string();
eprintln!("{} from {:?}", filename.as_str(), maybe_referrer);
let code = match filename.as_str() { let code = match filename.as_str() {
"a.js" => "import './b.js';", "a.js" => "import './b.js';",
"b.js" => "import './c.js';\nimport './a.js';", "b.js" => "import './c.js';\nimport './a.js';",
@ -1807,8 +1835,6 @@ mod tests {
} }
let loader = Rc::new(DynImportCircularLoader::default()); let loader = Rc::new(DynImportCircularLoader::default());
let resolve_count = loader.resolve_count.clone();
let load_count = loader.load_count.clone();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(loader), module_loader: Some(loader),
..Default::default() ..Default::default()
@ -1822,10 +1848,7 @@ mod tests {
.unwrap(); .unwrap();
let result = futures::executor::block_on(runtime.run_event_loop(false)); let result = futures::executor::block_on(runtime.run_event_loop(false));
eprintln!("result {:?}", result);
assert!(result.is_ok()); assert!(result.is_ok());
eprintln!("{}", resolve_count.load(Ordering::Relaxed));
eprintln!("{}", load_count.load(Ordering::Relaxed));
} }
#[test] #[test]
@ -1907,20 +1930,6 @@ mod tests {
futures::executor::block_on(fut); futures::executor::block_on(fut);
} }
const REDIRECT1_SRC: &str = r#"
import "./redirect2.js";
Deno.core.print("redirect1");
"#;
const REDIRECT2_SRC: &str = r#"
import "./redirect3.js";
Deno.core.print("redirect2");
"#;
const REDIRECT3_SRC: &str = r#"
Deno.core.print("redirect3");
"#;
#[test] #[test]
fn test_redirect_load() { fn test_redirect_load() {
let loader = MockLoader::new(); let loader = MockLoader::new();
@ -1934,7 +1943,6 @@ mod tests {
async move { async move {
let spec = resolve_url("file:///redirect1.js").unwrap(); let spec = resolve_url("file:///redirect1.js").unwrap();
let result = runtime.load_main_module(&spec, None).await; let result = runtime.load_main_module(&spec, None).await;
println!(">> result {:?}", result);
assert!(result.is_ok()); assert!(result.is_ok());
let redirect1_id = result.unwrap(); let redirect1_id = result.unwrap();
let _ = runtime.mod_evaluate(redirect1_id); let _ = runtime.mod_evaluate(redirect1_id);
@ -1990,22 +1998,6 @@ mod tests {
futures::executor::block_on(fut); futures::executor::block_on(fut);
} }
// main.js
const MAIN_SRC: &str = r#"
// never_ready.js never loads.
import "/never_ready.js";
// slow.js resolves after one tick.
import "/slow.js";
"#;
// slow.js
const SLOW_SRC: &str = r#"
// Circular import of never_ready.js
// Does this trigger two ModuleLoader calls? It shouldn't.
import "/never_ready.js";
import "/a.js";
"#;
#[test] #[test]
fn slow_never_ready_modules() { fn slow_never_ready_modules() {
run_in_task(|cx| { run_in_task(|cx| {
@ -2051,11 +2043,6 @@ mod tests {
}) })
} }
// bad_import.js
const BAD_IMPORT_SRC: &str = r#"
import "foo";
"#;
#[test] #[test]
fn loader_disappears_after_error() { fn loader_disappears_after_error() {
run_in_task(|cx| { run_in_task(|cx| {
@ -2078,17 +2065,17 @@ mod tests {
}) })
} }
const MAIN_WITH_CODE_SRC: &str = r#"
import { b } from "/b.js";
import { c } from "/c.js";
if (b() != 'b') throw Error();
if (c() != 'c') throw Error();
if (!import.meta.main) throw Error();
if (import.meta.url != 'file:///main_with_code.js') throw Error();
"#;
#[test] #[test]
fn recursive_load_main_with_code() { fn recursive_load_main_with_code() {
const MAIN_WITH_CODE_SRC: &str = r#"
import { b } from "/b.js";
import { c } from "/c.js";
if (b() != 'b') throw Error();
if (c() != 'c') throw Error();
if (!import.meta.main) throw Error();
if (import.meta.url != 'file:///main_with_code.js') throw Error();
"#;
let loader = MockLoader::new(); let loader = MockLoader::new();
let loads = loader.loads.clone(); let loads = loader.loads.clone();
let mut runtime = JsRuntime::new(RuntimeOptions { let mut runtime = JsRuntime::new(RuntimeOptions {
@ -2102,8 +2089,7 @@ mod tests {
let main_id_fut = runtime let main_id_fut = runtime
.load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned())) .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned()))
.boxed_local(); .boxed_local();
let main_id = let main_id = futures::executor::block_on(main_id_fut).unwrap();
futures::executor::block_on(main_id_fut).expect("Failed to load");
let _ = runtime.mod_evaluate(main_id); let _ = runtime.mod_evaluate(main_id);
futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); futures::executor::block_on(runtime.run_event_loop(false)).unwrap();
@ -2213,8 +2199,7 @@ mod tests {
let main_id_fut = runtime let main_id_fut = runtime
.load_main_module(&main_specifier, None) .load_main_module(&main_specifier, None)
.boxed_local(); .boxed_local();
let main_id = let main_id = futures::executor::block_on(main_id_fut).unwrap();
futures::executor::block_on(main_id_fut).expect("Failed to load");
let _ = runtime.mod_evaluate(main_id); let _ = runtime.mod_evaluate(main_id);
futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); futures::executor::block_on(runtime.run_event_loop(false)).unwrap();
@ -2223,15 +2208,13 @@ mod tests {
let side_id_fut = runtime let side_id_fut = runtime
.load_main_module(&side_specifier, None) .load_main_module(&side_specifier, None)
.boxed_local(); .boxed_local();
futures::executor::block_on(side_id_fut) futures::executor::block_on(side_id_fut).unwrap_err();
.expect_err("Should have failed to load second main module");
// And now try to load it as a side module // And now try to load it as a side module
let side_id_fut = runtime let side_id_fut = runtime
.load_side_module(&side_specifier, None) .load_side_module(&side_specifier, None)
.boxed_local(); .boxed_local();
let side_id = let side_id = futures::executor::block_on(side_id_fut).unwrap();
futures::executor::block_on(side_id_fut).expect("Failed to load");
let _ = runtime.mod_evaluate(side_id); let _ = runtime.mod_evaluate(side_id);
futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); futures::executor::block_on(runtime.run_event_loop(false)).unwrap();