summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/bindings.rs8
-rw-r--r--core/lib.rs5
-rw-r--r--core/module_specifier.rs282
-rw-r--r--core/modules.rs54
-rw-r--r--core/runtime.rs15
5 files changed, 155 insertions, 209 deletions
diff --git a/core/bindings.rs b/core/bindings.rs
index 08f244166..1f6b85174 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -454,9 +454,11 @@ fn eval_context(
}
*/
let tc_scope = &mut v8::TryCatch::new(scope);
- let name =
- v8::String::new(tc_scope, url.as_ref().map_or("<unknown>", Url::as_str))
- .unwrap();
+ let name = v8::String::new(
+ tc_scope,
+ url.as_ref().map_or(crate::DUMMY_SPECIFIER, Url::as_str),
+ )
+ .unwrap();
let origin = script_origin(tc_scope, name);
let maybe_script = v8::Script::compile(tc_scope, source, Some(&origin));
diff --git a/core/lib.rs b/core/lib.rs
index 9f4fec003..deea9d281 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -42,8 +42,13 @@ pub use crate::async_cell::AsyncRefFuture;
pub use crate::async_cell::RcLike;
pub use crate::async_cell::RcRef;
pub use crate::flags::v8_set_flags;
+pub use crate::module_specifier::resolve_import;
+pub use crate::module_specifier::resolve_path;
+pub use crate::module_specifier::resolve_url;
+pub use crate::module_specifier::resolve_url_or_path;
pub use crate::module_specifier::ModuleResolutionError;
pub use crate::module_specifier::ModuleSpecifier;
+pub use crate::module_specifier::DUMMY_SPECIFIER;
pub use crate::modules::FsModuleLoader;
pub use crate::modules::ModuleId;
pub use crate::modules::ModuleLoadId;
diff --git a/core/module_specifier.rs b/core/module_specifier.rs
index a9ce57099..dc6b4d6bf 100644
--- a/core/module_specifier.rs
+++ b/core/module_specifier.rs
@@ -1,9 +1,6 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use crate::normalize_path;
-use serde::de;
-use serde::Deserialize;
-use serde::Deserializer;
use std::env::current_dir;
use std::error::Error;
use std::fmt;
@@ -11,6 +8,8 @@ use std::path::PathBuf;
use url::ParseError;
use url::Url;
+pub const DUMMY_SPECIFIER: &str = "<unknown>";
+
/// Error indicating the reason resolving a module specifier failed.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ModuleResolutionError {
@@ -51,174 +50,126 @@ impl fmt::Display for ModuleResolutionError {
}
}
-#[derive(
- Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, Ord, PartialOrd,
-)]
/// Resolved module specifier
-pub struct ModuleSpecifier(Url);
-
-impl ModuleSpecifier {
- fn is_dummy_specifier(specifier: &str) -> bool {
- specifier == "<unknown>"
- }
-
- pub fn as_url(&self) -> &Url {
- &self.0
- }
-
- pub fn as_str(&self) -> &str {
- self.0.as_str()
- }
-
- /// Resolves module using this algorithm:
- /// https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier
- pub fn resolve_import(
- specifier: &str,
- base: &str,
- ) -> Result<ModuleSpecifier, ModuleResolutionError> {
- let url = match Url::parse(specifier) {
- // 1. Apply the URL parser to specifier.
- // If the result is not failure, return he result.
- Ok(url) => url,
-
- // 2. If specifier does not start with the character U+002F SOLIDUS (/),
- // the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./),
- // or the three-character sequence U+002E FULL STOP, U+002E FULL STOP,
- // U+002F SOLIDUS (../), return failure.
- Err(ParseError::RelativeUrlWithoutBase)
- if !(specifier.starts_with('/')
- || specifier.starts_with("./")
- || specifier.starts_with("../")) =>
- {
- let maybe_referrer = if base.is_empty() {
- None
- } else {
- Some(base.to_string())
- };
- return Err(ImportPrefixMissing(specifier.to_string(), maybe_referrer));
- }
-
- // 3. Return the result of applying the URL parser to specifier with base
- // URL as the base URL.
- Err(ParseError::RelativeUrlWithoutBase) => {
- let base = if ModuleSpecifier::is_dummy_specifier(base) {
- // Handle <unknown> case, happening under e.g. repl.
- // Use CWD for such case.
-
- // Forcefully join base to current dir.
- // Otherwise, later joining in Url would be interpreted in
- // the parent directory (appending trailing slash does not work)
- let path = current_dir().unwrap().join(base);
- Url::from_file_path(path).unwrap()
- } else {
- Url::parse(base).map_err(InvalidBaseUrl)?
- };
- base.join(&specifier).map_err(InvalidUrl)?
- }
-
- // If parsing the specifier as a URL failed for a different reason than
- // it being relative, always return the original error. We don't want to
- // return `ImportPrefixMissing` or `InvalidBaseUrl` if the real
- // problem lies somewhere else.
- Err(err) => return Err(InvalidUrl(err)),
- };
-
- Ok(ModuleSpecifier(url))
- }
-
- /// Converts a string representing an absolute URL into a ModuleSpecifier.
- pub fn resolve_url(
- url_str: &str,
- ) -> Result<ModuleSpecifier, ModuleResolutionError> {
- Url::parse(url_str)
- .map(ModuleSpecifier)
- .map_err(ModuleResolutionError::InvalidUrl)
- }
+pub type ModuleSpecifier = Url;
+
+/// Resolves module using this algorithm:
+/// https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier
+pub fn resolve_import(
+ specifier: &str,
+ base: &str,
+) -> Result<ModuleSpecifier, ModuleResolutionError> {
+ let url = match Url::parse(specifier) {
+ // 1. Apply the URL parser to specifier.
+ // If the result is not failure, return he result.
+ Ok(url) => url,
+
+ // 2. If specifier does not start with the character U+002F SOLIDUS (/),
+ // the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./),
+ // or the three-character sequence U+002E FULL STOP, U+002E FULL STOP,
+ // U+002F SOLIDUS (../), return failure.
+ Err(ParseError::RelativeUrlWithoutBase)
+ if !(specifier.starts_with('/')
+ || specifier.starts_with("./")
+ || specifier.starts_with("../")) =>
+ {
+ let maybe_referrer = if base.is_empty() {
+ None
+ } else {
+ Some(base.to_string())
+ };
+ return Err(ImportPrefixMissing(specifier.to_string(), maybe_referrer));
+ }
- /// Takes a string representing either an absolute URL or a file path,
- /// as it may be passed to deno as a command line argument.
- /// The string is interpreted as a URL if it starts with a valid URI scheme,
- /// e.g. 'http:' or 'file:' or 'git+ssh:'. If not, it's interpreted as a
- /// file path; if it is a relative path it's resolved relative to the current
- /// working directory.
- pub fn resolve_url_or_path(
- specifier: &str,
- ) -> Result<ModuleSpecifier, ModuleResolutionError> {
- if Self::specifier_has_uri_scheme(specifier) {
- Self::resolve_url(specifier)
- } else {
- Self::resolve_path(specifier)
+ // 3. Return the result of applying the URL parser to specifier with base
+ // URL as the base URL.
+ Err(ParseError::RelativeUrlWithoutBase) => {
+ let base = if base == DUMMY_SPECIFIER {
+ // Handle <unknown> case, happening under e.g. repl.
+ // Use CWD for such case.
+
+ // Forcefully join base to current dir.
+ // Otherwise, later joining in Url would be interpreted in
+ // the parent directory (appending trailing slash does not work)
+ let path = current_dir().unwrap().join(base);
+ Url::from_file_path(path).unwrap()
+ } else {
+ Url::parse(base).map_err(InvalidBaseUrl)?
+ };
+ base.join(&specifier).map_err(InvalidUrl)?
}
- }
- /// Converts a string representing a relative or absolute path into a
- /// ModuleSpecifier. A relative path is considered relative to the current
- /// working directory.
- pub fn resolve_path(
- path_str: &str,
- ) -> Result<ModuleSpecifier, ModuleResolutionError> {
- let path = current_dir().unwrap().join(path_str);
- let path = normalize_path(&path);
- Url::from_file_path(path.clone())
- .map(ModuleSpecifier)
- .map_err(|()| ModuleResolutionError::InvalidPath(path))
- }
+ // If parsing the specifier as a URL failed for a different reason than
+ // it being relative, always return the original error. We don't want to
+ // return `ImportPrefixMissing` or `InvalidBaseUrl` if the real
+ // problem lies somewhere else.
+ Err(err) => return Err(InvalidUrl(err)),
+ };
- /// Returns true if the input string starts with a sequence of characters
- /// that could be a valid URI scheme, like 'https:', 'git+ssh:' or 'data:'.
- ///
- /// According to RFC 3986 (https://tools.ietf.org/html/rfc3986#section-3.1),
- /// a valid scheme has the following format:
- /// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- ///
- /// We additionally require the scheme to be at least 2 characters long,
- /// because otherwise a windows path like c:/foo would be treated as a URL,
- /// while no schemes with a one-letter name actually exist.
- fn specifier_has_uri_scheme(specifier: &str) -> bool {
- let mut chars = specifier.chars();
- let mut len = 0usize;
- // THe first character must be a letter.
- match chars.next() {
- Some(c) if c.is_ascii_alphabetic() => len += 1,
- _ => return false,
- }
- // Second and following characters must be either a letter, number,
- // plus sign, minus sign, or dot.
- loop {
- match chars.next() {
- Some(c) if c.is_ascii_alphanumeric() || "+-.".contains(c) => len += 1,
- Some(':') if len >= 2 => return true,
- _ => return false,
- }
- }
- }
+ Ok(url)
}
-impl fmt::Display for ModuleSpecifier {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
+/// Converts a string representing an absolute URL into a ModuleSpecifier.
+pub fn resolve_url(
+ url_str: &str,
+) -> Result<ModuleSpecifier, ModuleResolutionError> {
+ Url::parse(url_str).map_err(ModuleResolutionError::InvalidUrl)
}
-impl From<Url> for ModuleSpecifier {
- fn from(url: Url) -> Self {
- ModuleSpecifier(url)
+/// Takes a string representing either an absolute URL or a file path,
+/// as it may be passed to deno as a command line argument.
+/// The string is interpreted as a URL if it starts with a valid URI scheme,
+/// e.g. 'http:' or 'file:' or 'git+ssh:'. If not, it's interpreted as a
+/// file path; if it is a relative path it's resolved relative to the current
+/// working directory.
+pub fn resolve_url_or_path(
+ specifier: &str,
+) -> Result<ModuleSpecifier, ModuleResolutionError> {
+ if specifier_has_uri_scheme(specifier) {
+ resolve_url(specifier)
+ } else {
+ resolve_path(specifier)
}
}
-impl PartialEq<String> for ModuleSpecifier {
- fn eq(&self, other: &String) -> bool {
- &self.to_string() == other
- }
+/// Converts a string representing a relative or absolute path into a
+/// ModuleSpecifier. A relative path is considered relative to the current
+/// working directory.
+pub fn resolve_path(
+ path_str: &str,
+) -> Result<ModuleSpecifier, ModuleResolutionError> {
+ let path = current_dir().unwrap().join(path_str);
+ let path = normalize_path(&path);
+ Url::from_file_path(path.clone())
+ .map_err(|()| ModuleResolutionError::InvalidPath(path))
}
-impl<'de> Deserialize<'de> for ModuleSpecifier {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- let url_str: String = Deserialize::deserialize(deserializer)?;
- ModuleSpecifier::resolve_url(&url_str).map_err(de::Error::custom)
+/// Returns true if the input string starts with a sequence of characters
+/// that could be a valid URI scheme, like 'https:', 'git+ssh:' or 'data:'.
+///
+/// According to RFC 3986 (https://tools.ietf.org/html/rfc3986#section-3.1),
+/// a valid scheme has the following format:
+/// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+///
+/// We additionally require the scheme to be at least 2 characters long,
+/// because otherwise a windows path like c:/foo would be treated as a URL,
+/// while no schemes with a one-letter name actually exist.
+fn specifier_has_uri_scheme(specifier: &str) -> bool {
+ let mut chars = specifier.chars();
+ let mut len = 0usize;
+ // THe first character must be a letter.
+ match chars.next() {
+ Some(c) if c.is_ascii_alphabetic() => len += 1,
+ _ => return false,
+ }
+ // Second and following characters must be either a letter, number,
+ // plus sign, minus sign, or dot.
+ loop {
+ match chars.next() {
+ Some(c) if c.is_ascii_alphanumeric() || "+-.".contains(c) => len += 1,
+ Some(':') if len >= 2 => return true,
+ _ => return false,
+ }
}
}
@@ -306,9 +257,7 @@ mod tests {
];
for (specifier, base, expected_url) in tests {
- let url = ModuleSpecifier::resolve_import(specifier, base)
- .unwrap()
- .to_string();
+ let url = resolve_import(specifier, base).unwrap().to_string();
assert_eq!(url, expected_url);
}
}
@@ -385,7 +334,7 @@ mod tests {
];
for (specifier, base, expected_err) in tests {
- let err = ModuleSpecifier::resolve_import(specifier, base).unwrap_err();
+ let err = resolve_import(specifier, base).unwrap_err();
assert_eq!(err, expected_err);
}
}
@@ -487,9 +436,7 @@ mod tests {
}
for (specifier, expected_url) in tests {
- let url = ModuleSpecifier::resolve_url_or_path(specifier)
- .unwrap()
- .to_string();
+ let url = resolve_url_or_path(specifier).unwrap().to_string();
assert_eq!(url, expected_url);
}
}
@@ -509,7 +456,7 @@ mod tests {
}
for (specifier, expected_err) in tests {
- let err = ModuleSpecifier::resolve_url_or_path(specifier).unwrap_err();
+ let err = resolve_url_or_path(specifier).unwrap_err();
assert_eq!(err, expected_err);
}
}
@@ -539,7 +486,7 @@ mod tests {
];
for (specifier, expected) in tests {
- let result = ModuleSpecifier::specifier_has_uri_scheme(specifier);
+ let result = specifier_has_uri_scheme(specifier);
assert_eq!(result, expected);
}
}
@@ -565,8 +512,7 @@ mod tests {
fn test_deserialize_module_specifier() {
let actual: ModuleSpecifier =
from_value(json!("http://deno.land/x/mod.ts")).unwrap();
- let expected =
- ModuleSpecifier::resolve_url("http://deno.land/x/mod.ts").unwrap();
+ let expected = resolve_url("http://deno.land/x/mod.ts").unwrap();
assert_eq!(actual, expected);
}
}
diff --git a/core/modules.rs b/core/modules.rs
index 815db2fb9..aefb3e491 100644
--- a/core/modules.rs
+++ b/core/modules.rs
@@ -145,7 +145,7 @@ impl ModuleLoader for FsModuleLoader {
referrer: &str,
_is_main: bool,
) -> Result<ModuleSpecifier, AnyError> {
- Ok(ModuleSpecifier::resolve_import(specifier, referrer)?)
+ Ok(crate::resolve_import(specifier, referrer)?)
}
fn load(
@@ -157,7 +157,7 @@ impl ModuleLoader for FsModuleLoader {
) -> Pin<Box<ModuleSourceFuture>> {
let module_specifier = module_specifier.clone();
async move {
- let path = module_specifier.as_url().to_file_path().map_err(|_| {
+ let path = module_specifier.to_file_path().map_err(|_| {
generic_error(format!(
"Provided module specifier \"{}\" is not a file URL.",
module_specifier
@@ -649,11 +649,10 @@ mod tests {
eprintln!(">> RESOLVING, S: {}, R: {}", specifier, referrer);
- let output_specifier =
- match ModuleSpecifier::resolve_import(specifier, referrer) {
- Ok(specifier) => specifier,
- Err(..) => return Err(MockError::ResolveErr.into()),
- };
+ let output_specifier = match crate::resolve_import(specifier, referrer) {
+ Ok(specifier) => specifier,
+ Err(..) => return Err(MockError::ResolveErr.into()),
+ };
if mock_source_code(&output_specifier.to_string()).is_some() {
Ok(output_specifier)
@@ -715,7 +714,7 @@ mod tests {
module_loader: Some(loader),
..Default::default()
});
- let spec = ModuleSpecifier::resolve_url("file:///a.js").unwrap();
+ let spec = crate::resolve_url("file:///a.js").unwrap();
let a_id_fut = runtime.load_module(&spec, None);
let a_id = futures::executor::block_on(a_id_fut).expect("Failed to load");
@@ -741,17 +740,17 @@ mod tests {
assert_eq!(
modules.get_children(a_id),
Some(&vec![
- ModuleSpecifier::resolve_url("file:///b.js").unwrap(),
- ModuleSpecifier::resolve_url("file:///c.js").unwrap()
+ crate::resolve_url("file:///b.js").unwrap(),
+ crate::resolve_url("file:///c.js").unwrap()
])
);
assert_eq!(
modules.get_children(b_id),
- Some(&vec![ModuleSpecifier::resolve_url("file:///c.js").unwrap()])
+ Some(&vec![crate::resolve_url("file:///c.js").unwrap()])
);
assert_eq!(
modules.get_children(c_id),
- Some(&vec![ModuleSpecifier::resolve_url("file:///d.js").unwrap()])
+ Some(&vec![crate::resolve_url("file:///d.js").unwrap()])
);
assert_eq!(modules.get_children(d_id), Some(&vec![]));
}
@@ -782,7 +781,7 @@ mod tests {
});
let fut = async move {
- let spec = ModuleSpecifier::resolve_url("file:///circular1.js").unwrap();
+ let spec = crate::resolve_url("file:///circular1.js").unwrap();
let result = runtime.load_module(&spec, None).await;
assert!(result.is_ok());
let circular1_id = result.unwrap();
@@ -807,16 +806,12 @@ mod tests {
assert_eq!(
modules.get_children(circular1_id),
- Some(&vec![
- ModuleSpecifier::resolve_url("file:///circular2.js").unwrap()
- ])
+ Some(&vec![crate::resolve_url("file:///circular2.js").unwrap()])
);
assert_eq!(
modules.get_children(circular2_id),
- Some(&vec![
- ModuleSpecifier::resolve_url("file:///circular3.js").unwrap()
- ])
+ Some(&vec![crate::resolve_url("file:///circular3.js").unwrap()])
);
assert!(modules.get_id("file:///circular3.js").is_some());
@@ -824,8 +819,8 @@ mod tests {
assert_eq!(
modules.get_children(circular3_id),
Some(&vec![
- ModuleSpecifier::resolve_url("file:///circular1.js").unwrap(),
- ModuleSpecifier::resolve_url("file:///circular2.js").unwrap()
+ crate::resolve_url("file:///circular1.js").unwrap(),
+ crate::resolve_url("file:///circular2.js").unwrap()
])
);
}
@@ -858,7 +853,7 @@ mod tests {
});
let fut = async move {
- let spec = ModuleSpecifier::resolve_url("file:///redirect1.js").unwrap();
+ let spec = crate::resolve_url("file:///redirect1.js").unwrap();
let result = runtime.load_module(&spec, None).await;
println!(">> result {:?}", result);
assert!(result.is_ok());
@@ -923,7 +918,7 @@ mod tests {
module_loader: Some(loader),
..Default::default()
});
- let spec = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
+ let spec = crate::resolve_url("file:///main.js").unwrap();
let mut recursive_load = runtime.load_module(&spec, None).boxed_local();
let result = recursive_load.poll_unpin(&mut cx);
@@ -971,7 +966,7 @@ mod tests {
module_loader: Some(loader),
..Default::default()
});
- let spec = ModuleSpecifier::resolve_url("file:///bad_import.js").unwrap();
+ let spec = crate::resolve_url("file:///bad_import.js").unwrap();
let mut load_fut = runtime.load_module(&spec, None).boxed_local();
let result = load_fut.poll_unpin(&mut cx);
if let Poll::Ready(Err(err)) = result {
@@ -1005,8 +1000,7 @@ mod tests {
// In default resolution code should be empty.
// Instead we explicitly pass in our own code.
// The behavior should be very similar to /a.js.
- let spec =
- ModuleSpecifier::resolve_url("file:///main_with_code.js").unwrap();
+ let spec = crate::resolve_url("file:///main_with_code.js").unwrap();
let main_id_fut = runtime
.load_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned()))
.boxed_local();
@@ -1033,17 +1027,17 @@ mod tests {
assert_eq!(
modules.get_children(main_id),
Some(&vec![
- ModuleSpecifier::resolve_url("file:///b.js").unwrap(),
- ModuleSpecifier::resolve_url("file:///c.js").unwrap()
+ crate::resolve_url("file:///b.js").unwrap(),
+ crate::resolve_url("file:///c.js").unwrap()
])
);
assert_eq!(
modules.get_children(b_id),
- Some(&vec![ModuleSpecifier::resolve_url("file:///c.js").unwrap()])
+ Some(&vec![crate::resolve_url("file:///c.js").unwrap()])
);
assert_eq!(
modules.get_children(c_id),
- Some(&vec![ModuleSpecifier::resolve_url("file:///d.js").unwrap()])
+ Some(&vec![crate::resolve_url("file:///d.js").unwrap()])
);
assert_eq!(modules.get_children(d_id), Some(&vec![]));
}
diff --git a/core/runtime.rs b/core/runtime.rs
index 9db1669cd..31229aaa3 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -1224,8 +1224,7 @@ impl JsRuntime {
let is_main =
load.state == LoadState::LoadingRoot && !load.is_dynamic_import();
- let referrer_specifier =
- ModuleSpecifier::resolve_url(&module_url_found).unwrap();
+ let referrer_specifier = crate::resolve_url(&module_url_found).unwrap();
let state_rc = Self::state(self.v8_isolate());
// #A There are 3 cases to handle at this moment:
@@ -2200,7 +2199,7 @@ pub mod tests {
self.count.fetch_add(1, Ordering::Relaxed);
assert_eq!(specifier, "./b.js");
assert_eq!(referrer, "file:///a.js");
- let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap();
+ let s = crate::resolve_import(specifier, referrer).unwrap();
Ok(s)
}
@@ -2272,7 +2271,7 @@ pub mod tests {
let imports = state.modules.get_children(mod_a);
assert_eq!(
imports,
- Some(&vec![ModuleSpecifier::resolve_url("file:///b.js").unwrap()])
+ Some(&vec![crate::resolve_url("file:///b.js").unwrap()])
);
}
let mod_b = runtime
@@ -2313,7 +2312,7 @@ pub mod tests {
self.count.fetch_add(1, Ordering::Relaxed);
assert_eq!(specifier, "/foo.js");
assert_eq!(referrer, "file:///dyn_import2.js");
- let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap();
+ let s = crate::resolve_import(specifier, referrer).unwrap();
Ok(s)
}
@@ -2377,7 +2376,7 @@ pub mod tests {
assert!(c < 4);
assert_eq!(specifier, "./b.js");
assert_eq!(referrer, "file:///dyn_import3.js");
- let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap();
+ let s = crate::resolve_import(specifier, referrer).unwrap();
Ok(s)
}
@@ -2504,7 +2503,7 @@ pub mod tests {
) -> Result<ModuleSpecifier, AnyError> {
assert_eq!(specifier, "file:///main.js");
assert_eq!(referrer, ".");
- let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap();
+ let s = crate::resolve_import(specifier, referrer).unwrap();
Ok(s)
}
@@ -2526,7 +2525,7 @@ pub mod tests {
..Default::default()
});
- let specifier = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
+ let specifier = crate::resolve_url("file:///main.js").unwrap();
let source_code = "Deno.core.print('hello\\n')".to_string();
let module_id = futures::executor::block_on(