1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-25 08:39:09 -05:00

refactor: integrate deno_graph breaking changes (#13495)

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Kitson Kelly 2022-02-01 09:33:57 +11:00 committed by GitHub
parent 5490cfed20
commit 7d356250e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 433 additions and 359 deletions

53
Cargo.lock generated
View file

@ -115,9 +115,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.52" version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
@ -720,7 +720,7 @@ dependencies = [
"clap_complete", "clap_complete",
"clap_complete_fig", "clap_complete_fig",
"data-url", "data-url",
"deno_ast", "deno_ast 0.10.0",
"deno_bench_util", "deno_bench_util",
"deno_broadcast_channel", "deno_broadcast_channel",
"deno_console", "deno_console",
@ -790,6 +790,23 @@ name = "deno_ast"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e81ceec755f9e4e270e8d7ef4ade1921eddc1717dea092c726b088f9c074721b" checksum = "e81ceec755f9e4e270e8d7ef4ade1921eddc1717dea092c726b088f9c074721b"
dependencies = [
"anyhow",
"base64 0.13.0",
"data-url",
"serde",
"swc_atoms",
"swc_common",
"swc_ecmascript",
"text_lines",
"url",
]
[[package]]
name = "deno_ast"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a2780a628fd2fd52c81ef3f9d2bda0609a662b9e4f85623c29051c277363f65"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.13.0", "base64 0.13.0",
@ -835,7 +852,7 @@ name = "deno_core"
version = "0.117.0" version = "0.117.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast 0.9.0",
"futures", "futures",
"indexmap", "indexmap",
"libc", "libc",
@ -882,12 +899,12 @@ dependencies = [
[[package]] [[package]]
name = "deno_doc" name = "deno_doc"
version = "0.26.1" version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82f45d6513b789c04adf0915ca3c3c696f5f5f9379a82834ad4f783fbaa8b3a" checksum = "a37040708cc0c8f1f826073774ea4406bee735d8cb6aacd0b9891e27be7c13bd"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"deno_ast", "deno_ast 0.10.0",
"deno_graph", "deno_graph",
"futures", "futures",
"lazy_static", "lazy_static",
@ -928,14 +945,14 @@ dependencies = [
[[package]] [[package]]
name = "deno_graph" name = "deno_graph"
version = "0.18.0" version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b2a21feedd2fde8846a8b94855498ff7e1c59bdf972a06a6faf228999c1f7fd" checksum = "86eccec721ae9dceae2e6cbd83b63de3ef810e7c39357c9a867c98b9633d4775"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"data-url", "data-url",
"deno_ast", "deno_ast 0.10.0",
"futures", "futures",
"lazy_static", "lazy_static",
"parking_lot", "parking_lot",
@ -964,12 +981,12 @@ dependencies = [
[[package]] [[package]]
name = "deno_lint" name = "deno_lint"
version = "0.22.0" version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cf1715d924e6fdf45847868b31742ed305fb6270747c6046dc3c19f67c0d2f5" checksum = "c838bbcaffd4143940068bea8eb5faa6de1ed8c3d3d0a63d8ed7319a967f47bd"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast 0.10.0",
"derive_more", "derive_more",
"if_chain", "if_chain",
"log", "log",
@ -1204,9 +1221,9 @@ dependencies = [
[[package]] [[package]]
name = "dprint-core" name = "dprint-core"
version = "0.49.0" version = "0.49.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8113ac9998173de8fa4fcf6fc7fe80c15c93df290828afa060dbdbb84337afbf" checksum = "50bcbca32c5b922a8b4ededae420ca17aa7c1ac03131bebe7f78d682945e21a1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bumpalo", "bumpalo",
@ -1241,12 +1258,12 @@ dependencies = [
[[package]] [[package]]
name = "dprint-plugin-typescript" name = "dprint-plugin-typescript"
version = "0.62.0" version = "0.62.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e9b87d22638bc08075c827ae568e02b07fbf262142db90895383bac3f5a67e" checksum = "312bd921ea751a303703123e2e26e28456abd6ae9ff42dce478e16f613154874"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast 0.10.0",
"dprint-core", "dprint-core",
"parking_lot_core", "parking_lot_core",
"rustc-hash", "rustc-hash",

View file

@ -45,11 +45,11 @@ winapi = "=0.3.9"
winres = "=0.1.11" winres = "=0.1.11"
[dependencies] [dependencies]
deno_ast = { version = "0.9.0", features = ["bundler", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "transpiling", "typescript", "view", "visit"] } deno_ast = { version = "0.10.0", features = ["bundler", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "transpiling", "typescript", "view", "visit"] }
deno_core = { version = "0.117.0", path = "../core" } deno_core = { version = "0.117.0", path = "../core" }
deno_doc = "0.26.0" deno_doc = "0.28.0"
deno_graph = "0.18.0" deno_graph = "0.21.1"
deno_lint = { version = "0.22.0", features = ["docs"] } deno_lint = { version = "0.23.0", features = ["docs"] }
deno_runtime = { version = "0.43.0", path = "../runtime" } deno_runtime = { version = "0.43.0", path = "../runtime" }
atty = "=0.2.14" atty = "=0.2.14"
@ -63,7 +63,7 @@ data-url = "=0.1.1"
dissimilar = "=1.0.2" dissimilar = "=1.0.2"
dprint-plugin-json = "=0.14.0" dprint-plugin-json = "=0.14.0"
dprint-plugin-markdown = "=0.12.1" dprint-plugin-markdown = "=0.12.1"
dprint-plugin-typescript = "=0.62.0" dprint-plugin-typescript = "=0.62.1"
encoding_rs = "=0.8.29" encoding_rs = "=0.8.29"
env_logger = "=0.8.4" env_logger = "=0.8.4"
fancy-regex = "=0.7.1" fancy-regex = "=0.7.1"

View file

@ -9,6 +9,7 @@ use deno_core::serde_json::Map;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::source::ResolveResponse;
use deno_graph::source::Resolver; use deno_graph::source::Resolver;
use regex::Regex; use regex::Regex;
use std::path::PathBuf; use std::path::PathBuf;
@ -31,24 +32,28 @@ impl Resolver for NodeEsmResolver {
&self, &self,
specifier: &str, specifier: &str,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> { ) -> ResolveResponse {
// First try to resolve using import map, ignoring any errors // First try to resolve using import map, ignoring any errors
if !specifier.starts_with("node:") { if !specifier.starts_with("node:") {
if let Some(import_map_resolver) = &self.maybe_import_map_resolver { if let Some(import_map_resolver) = &self.maybe_import_map_resolver {
if let Ok(specifier) = import_map_resolver.resolve(specifier, referrer) let response = import_map_resolver.resolve(specifier, referrer);
{ if !matches!(response, ResolveResponse::Err(_)) {
return Ok(specifier); return response;
} }
} }
} }
let current_dir = match std::env::current_dir() {
Ok(path) => path,
Err(err) => return ResolveResponse::Err(err.into()),
};
let node_resolution = let node_resolution =
node_resolve(specifier, referrer.as_str(), &std::env::current_dir()?); node_resolve(specifier, referrer.as_str(), &current_dir);
match node_resolution { match node_resolution {
Ok(specifier) => { Ok(resolve_response) => {
// If node resolution succeeded, return the specifier // If node resolution succeeded, return the specifier
Ok(specifier) resolve_response
} }
Err(err) => { Err(err) => {
// If node resolution failed, check if it's because of unsupported // If node resolution failed, check if it's because of unsupported
@ -57,11 +62,13 @@ impl Resolver for NodeEsmResolver {
.to_string() .to_string()
.starts_with("[ERR_UNSUPPORTED_ESM_URL_SCHEME]") .starts_with("[ERR_UNSUPPORTED_ESM_URL_SCHEME]")
{ {
return deno_core::resolve_import(specifier, referrer.as_str()) return match deno_core::resolve_import(specifier, referrer.as_str()) {
.map_err(|err| err.into()); Ok(specifier) => ResolveResponse::Esm(specifier),
Err(err) => ResolveResponse::Err(err.into()),
};
} }
Err(err) ResolveResponse::Err(err)
} }
} }
} }
@ -75,16 +82,16 @@ fn node_resolve(
specifier: &str, specifier: &str,
referrer: &str, referrer: &str,
cwd: &std::path::Path, cwd: &std::path::Path,
) -> Result<ModuleSpecifier, AnyError> { ) -> Result<ResolveResponse, AnyError> {
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it // TODO(bartlomieju): skipped "policy" part as we don't plan to support it
if let Some(resolved) = crate::compat::try_resolve_builtin_module(specifier) { if let Some(resolved) = crate::compat::try_resolve_builtin_module(specifier) {
return Ok(resolved); return Ok(ResolveResponse::Esm(resolved));
} }
if let Ok(url) = Url::parse(specifier) { if let Ok(url) = Url::parse(specifier) {
if url.scheme() == "data" { if url.scheme() == "data" {
return Ok(url); return Ok(ResolveResponse::Specifier(url));
} }
let protocol = url.scheme(); let protocol = url.scheme();
@ -95,7 +102,7 @@ fn node_resolve(
if let Some(resolved) = if let Some(resolved) =
crate::compat::try_resolve_builtin_module(&specifier) crate::compat::try_resolve_builtin_module(&specifier)
{ {
return Ok(resolved); return Ok(ResolveResponse::Esm(resolved));
} else { } else {
return Err(generic_error(format!("Unknown module {}", specifier))); return Err(generic_error(format!("Unknown module {}", specifier)));
} }
@ -107,7 +114,8 @@ fn node_resolve(
if referrer.starts_with("data:") { if referrer.starts_with("data:") {
let referrer_url = Url::parse(referrer)?; let referrer_url = Url::parse(referrer)?;
return referrer_url.join(specifier).map_err(AnyError::from); let url = referrer_url.join(specifier).map_err(AnyError::from)?;
return Ok(ResolveResponse::Specifier(url));
} }
} }
@ -121,9 +129,23 @@ fn node_resolve(
let conditions = DEFAULT_CONDITIONS; let conditions = DEFAULT_CONDITIONS;
let url = module_resolve(specifier, &parent_url, conditions)?; let url = module_resolve(specifier, &parent_url, conditions)?;
let resolve_response = if url.as_str().starts_with("http") {
ResolveResponse::Esm(url)
} else if url.as_str().ends_with(".js") {
let package_config = get_package_scope_config(&url)?;
if package_config.typ == "module" {
ResolveResponse::Esm(url)
} else {
ResolveResponse::CommonJs(url)
}
} else if url.as_str().ends_with(".cjs") {
ResolveResponse::CommonJs(url)
} else {
ResolveResponse::Esm(url)
};
// TODO(bartlomieju): skipped checking errors for commonJS resolution and // TODO(bartlomieju): skipped checking errors for commonJS resolution and
// "preserveSymlinksMain"/"preserveSymlinks" options. // "preserveSymlinksMain"/"preserveSymlinks" options.
Ok(url) Ok(resolve_response)
} }
fn to_file_path(url: &ModuleSpecifier) -> PathBuf { fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
@ -1146,7 +1168,8 @@ mod tests {
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
let expected = let expected =
Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap(); Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap();
assert_eq!(actual, expected); assert!(matches!(actual, ResolveResponse::Esm(_)));
assert_eq!(actual.to_result().unwrap(), expected);
let actual = node_resolve( let actual = node_resolve(
"data:application/javascript,console.log(\"Hello%20Deno\");", "data:application/javascript,console.log(\"Hello%20Deno\");",
@ -1154,12 +1177,11 @@ mod tests {
&cwd, &cwd,
) )
.unwrap(); .unwrap();
eprintln!("actual {}", actual); let expected =
assert_eq!(
actual,
Url::parse("data:application/javascript,console.log(\"Hello%20Deno\");") Url::parse("data:application/javascript,console.log(\"Hello%20Deno\");")
.unwrap() .unwrap();
); assert!(matches!(actual, ResolveResponse::Specifier(_)));
assert_eq!(actual.to_result().unwrap(), expected);
} }
#[test] #[test]
@ -1169,7 +1191,8 @@ mod tests {
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
let expected = let expected =
Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap(); Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap();
assert_eq!(actual, expected); matches!(actual, ResolveResponse::Esm(_));
assert_eq!(actual.to_result().unwrap(), expected);
} }
#[test] #[test]
@ -1179,13 +1202,15 @@ mod tests {
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
let foo_js = let foo_js =
Url::from_file_path(cwd.join("node_modules/foo/foo.js")).unwrap(); Url::from_file_path(cwd.join("node_modules/foo/foo.js")).unwrap();
assert_eq!(actual, foo_js); assert!(matches!(actual, ResolveResponse::Esm(_)));
assert_eq!(actual.to_result().unwrap(), foo_js);
let actual = node_resolve("bar", foo_js.as_str(), &cwd).unwrap(); let actual = node_resolve("bar", foo_js.as_str(), &cwd).unwrap();
let bar_js = let bar_js =
Url::from_file_path(cwd.join("node_modules/bar/bar.js")).unwrap(); Url::from_file_path(cwd.join("node_modules/bar/bar.js")).unwrap();
assert_eq!(actual, bar_js); assert!(matches!(actual, ResolveResponse::Esm(_)));
assert_eq!(actual.to_result().unwrap(), bar_js);
} }
#[test] #[test]
@ -1196,12 +1221,12 @@ mod tests {
Url::parse("https://deno.land/std@0.123.0/node/http.ts").unwrap(); Url::parse("https://deno.land/std@0.123.0/node/http.ts").unwrap();
let actual = node_resolve("http", main.as_str(), &cwd).unwrap(); let actual = node_resolve("http", main.as_str(), &cwd).unwrap();
println!("actual {}", actual); assert!(matches!(actual, ResolveResponse::Esm(_)));
assert_eq!(actual, expected); assert_eq!(actual.to_result().unwrap(), expected);
let actual = node_resolve("node:http", main.as_str(), &cwd).unwrap(); let actual = node_resolve("node:http", main.as_str(), &cwd).unwrap();
println!("actual {}", actual); assert!(matches!(actual, ResolveResponse::Esm(_)));
assert_eq!(actual, expected); assert_eq!(actual.to_result().unwrap(), expected);
} }
#[test] #[test]
@ -1214,14 +1239,16 @@ mod tests {
cwd.join("node_modules/imports_exports/import_export.js"), cwd.join("node_modules/imports_exports/import_export.js"),
) )
.unwrap(); .unwrap();
assert_eq!(actual, expected); assert!(matches!(actual, ResolveResponse::CommonJs(_)));
assert_eq!(actual.to_result().unwrap(), expected);
// check that `imports` mapping works correctly // check that `imports` mapping works correctly
let cwd = testdir("conditions/node_modules/imports_exports"); let cwd = testdir("conditions/node_modules/imports_exports");
let main = Url::from_file_path(cwd.join("import_export.js")).unwrap(); let main = Url::from_file_path(cwd.join("import_export.js")).unwrap();
let actual = node_resolve("#dep", main.as_str(), &cwd).unwrap(); let actual = node_resolve("#dep", main.as_str(), &cwd).unwrap();
let expected = Url::from_file_path(cwd.join("import_polyfill.js")).unwrap(); let expected = Url::from_file_path(cwd.join("import_polyfill.js")).unwrap();
assert_eq!(actual, expected); assert!(matches!(actual, ResolveResponse::CommonJs(_)));
assert_eq!(actual.to_result().unwrap(), expected);
} }
#[test] #[test]

View file

@ -49,6 +49,7 @@ use deno_core::ModuleSpecifier;
use deno_graph::MediaType; use deno_graph::MediaType;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_graph::ModuleGraphError; use deno_graph::ModuleGraphError;
use deno_graph::ModuleKind;
use deno_graph::ResolutionError; use deno_graph::ResolutionError;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
@ -269,7 +270,7 @@ pub(crate) fn get_ts_config(
/// the emittable files in the roots, so they get type checked and optionally /// the emittable files in the roots, so they get type checked and optionally
/// emitted, otherwise they would be ignored if only imported into JavaScript. /// emitted, otherwise they would be ignored if only imported into JavaScript.
fn get_tsc_roots( fn get_tsc_roots(
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
graph_data: &GraphData, graph_data: &GraphData,
check_js: bool, check_js: bool,
) -> Vec<(ModuleSpecifier, MediaType)> { ) -> Vec<(ModuleSpecifier, MediaType)> {
@ -292,7 +293,7 @@ fn get_tsc_roots(
} else { } else {
roots roots
.iter() .iter()
.filter_map(|specifier| match graph_data.get(specifier) { .filter_map(|(specifier, _)| match graph_data.get(specifier) {
Some(ModuleEntry::Module { media_type, .. }) => { Some(ModuleEntry::Module { media_type, .. }) => {
Some((specifier.clone(), *media_type)) Some((specifier.clone(), *media_type))
} }
@ -313,8 +314,15 @@ fn get_version(source_bytes: &[u8], config_bytes: &[u8]) -> String {
]) ])
} }
/// Determine if a given media type is emittable or not. /// Determine if a given module kind and media type is emittable or not.
pub(crate) fn is_emittable(media_type: &MediaType, include_js: bool) -> bool { pub(crate) fn is_emittable(
kind: &ModuleKind,
media_type: &MediaType,
include_js: bool,
) -> bool {
if matches!(kind, ModuleKind::Synthetic) {
return false;
}
match &media_type { match &media_type {
MediaType::TypeScript MediaType::TypeScript
| MediaType::Mts | MediaType::Mts
@ -366,7 +374,7 @@ pub(crate) struct CheckEmitResult {
/// It is expected that it is determined if a check and/or emit is validated /// It is expected that it is determined if a check and/or emit is validated
/// before the function is called. /// before the function is called.
pub(crate) fn check_and_maybe_emit( pub(crate) fn check_and_maybe_emit(
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
graph_data: Arc<RwLock<GraphData>>, graph_data: Arc<RwLock<GraphData>>,
cache: &mut dyn Cacher, cache: &mut dyn Cacher,
options: CheckOptions, options: CheckOptions,
@ -387,7 +395,7 @@ pub(crate) fn check_and_maybe_emit(
} }
let root_names = get_tsc_roots(roots, &segment_graph_data, check_js); let root_names = get_tsc_roots(roots, &segment_graph_data, check_js);
if options.log_checks { if options.log_checks {
for root in roots { for (root, _) in roots {
let root_str = root.to_string(); let root_str = root.to_string();
// `$deno` specifiers are internal, don't print them. // `$deno` specifiers are internal, don't print them.
if !root_str.contains("$deno") { if !root_str.contains("$deno") {
@ -401,7 +409,7 @@ pub(crate) fn check_and_maybe_emit(
let maybe_tsbuildinfo = if options.reload { let maybe_tsbuildinfo = if options.reload {
None None
} else { } else {
cache.get(CacheType::TypeScriptBuildInfo, &roots[0]) cache.get(CacheType::TypeScriptBuildInfo, &roots[0].0)
}; };
// to make tsc build info work, we need to consistently hash modules, so that // to make tsc build info work, we need to consistently hash modules, so that
// tsc can better determine if an emit is still valid or not, so we provide // tsc can better determine if an emit is still valid or not, so we provide
@ -442,7 +450,7 @@ pub(crate) fn check_and_maybe_emit(
if let Some(info) = &response.maybe_tsbuildinfo { if let Some(info) = &response.maybe_tsbuildinfo {
// while we retrieve the build info for just the first module, it can be // while we retrieve the build info for just the first module, it can be
// used for all the roots in the graph, so we will cache it for all roots // used for all the roots in the graph, so we will cache it for all roots
for root in roots { for (root, _) in roots {
cache.set(CacheType::TypeScriptBuildInfo, root, info.clone())?; cache.set(CacheType::TypeScriptBuildInfo, root, info.clone())?;
} }
} }
@ -547,8 +555,8 @@ impl swc::bundler::Load for BundleLoader<'_> {
if let Some(m) = self.graph.get(specifier) { if let Some(m) = self.graph.get(specifier) {
let (fm, module) = transpile_module( let (fm, module) = transpile_module(
specifier, specifier,
m.maybe_source().unwrap_or(""), m.maybe_source.as_ref().map(|s| s.as_str()).unwrap_or(""),
*m.media_type(), m.media_type,
self.emit_options, self.emit_options,
self.cm.clone(), self.cm.clone(),
)?; )?;
@ -716,7 +724,7 @@ pub(crate) fn bundle(
let mut entries = HashMap::new(); let mut entries = HashMap::new();
entries.insert( entries.insert(
"bundle".to_string(), "bundle".to_string(),
swc::common::FileName::Url(graph.roots[0].clone()), swc::common::FileName::Url(graph.roots[0].0.clone()),
); );
let output = bundler let output = bundler
.bundle(entries) .bundle(entries)
@ -795,21 +803,32 @@ pub(crate) fn emit(
let mut file_count = 0_u32; let mut file_count = 0_u32;
for module in graph.modules() { for module in graph.modules() {
file_count += 1; file_count += 1;
if !is_emittable(&module.media_type, include_js) { if !is_emittable(&module.kind, &module.media_type, include_js) {
continue; continue;
} }
let needs_reload = let needs_reload =
options.reload && !options.reload_exclusions.contains(&module.specifier); options.reload && !options.reload_exclusions.contains(&module.specifier);
let version = get_version(module.source.as_bytes(), &config_bytes); let version = get_version(
let is_valid = cache module.maybe_source.as_ref().map(|s| s.as_bytes()).unwrap(),
.get(CacheType::Version, &module.specifier) &config_bytes,
.map_or(false, |v| { );
v == get_version(module.source.as_bytes(), &config_bytes) let is_valid =
}); cache
.get(CacheType::Version, &module.specifier)
.map_or(false, |v| {
v == get_version(
module.maybe_source.as_ref().map(|s| s.as_bytes()).unwrap(),
&config_bytes,
)
});
if is_valid && !needs_reload { if is_valid && !needs_reload {
continue; continue;
} }
let transpiled_source = module.parsed_source.transpile(&emit_options)?; let transpiled_source = module
.maybe_parsed_source
.as_ref()
.map(|ps| ps.transpile(&emit_options))
.unwrap()?;
emit_count += 1; emit_count += 1;
cache.set(CacheType::Emit, &module.specifier, transpiled_source.text)?; cache.set(CacheType::Emit, &module.specifier, transpiled_source.text)?;
if let Some(map) = transpiled_source.source_map { if let Some(map) = transpiled_source.source_map {
@ -897,8 +916,8 @@ impl fmt::Display for GraphError {
ModuleGraphError::ResolutionError(err) => { ModuleGraphError::ResolutionError(err) => {
if matches!( if matches!(
err, err,
ResolutionError::InvalidDowngrade(_, _) ResolutionError::InvalidDowngrade { .. }
| ResolutionError::InvalidLocalImport(_, _) | ResolutionError::InvalidLocalImport { .. }
) { ) {
write!(f, "{}", err.to_string_with_range()) write!(f, "{}", err.to_string_with_range())
} else { } else {
@ -918,7 +937,7 @@ pub(crate) fn to_file_map(
) -> HashMap<String, String> { ) -> HashMap<String, String> {
let mut files = HashMap::new(); let mut files = HashMap::new();
for (_, result) in graph.specifiers().into_iter() { for (_, result) in graph.specifiers().into_iter() {
if let Ok((specifier, media_type)) = result { if let Ok((specifier, _, media_type)) = result {
if let Some(emit) = cache.get(CacheType::Emit, &specifier) { if let Some(emit) = cache.get(CacheType::Emit, &specifier) {
files.insert(format!("{}.js", specifier), emit); files.insert(format!("{}.js", specifier), emit);
if let Some(map) = cache.get(CacheType::SourceMap, &specifier) { if let Some(map) = cache.get(CacheType::SourceMap, &specifier) {
@ -935,7 +954,11 @@ pub(crate) fn to_file_map(
if let Some(module) = graph.get(&specifier) { if let Some(module) = graph.get(&specifier) {
files.insert( files.insert(
specifier.to_string(), specifier.to_string(),
module.maybe_source().unwrap_or("").to_string(), module
.maybe_source
.as_ref()
.map(|s| s.to_string())
.unwrap_or_else(|| "".to_string()),
); );
} }
} }
@ -1027,16 +1050,29 @@ mod tests {
#[test] #[test]
fn test_is_emittable() { fn test_is_emittable() {
assert!(is_emittable(&MediaType::TypeScript, false)); assert!(is_emittable(
assert!(!is_emittable(&MediaType::Dts, false)); &ModuleKind::Esm,
assert!(!is_emittable(&MediaType::Dcts, false)); &MediaType::TypeScript,
assert!(!is_emittable(&MediaType::Dmts, false)); false
assert!(is_emittable(&MediaType::Tsx, false)); ));
assert!(!is_emittable(&MediaType::JavaScript, false)); assert!(!is_emittable(
assert!(!is_emittable(&MediaType::Cjs, false)); &ModuleKind::Synthetic,
assert!(!is_emittable(&MediaType::Mjs, false)); &MediaType::TypeScript,
assert!(is_emittable(&MediaType::JavaScript, true)); false
assert!(is_emittable(&MediaType::Jsx, false)); ));
assert!(!is_emittable(&MediaType::Json, false)); assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Dts, false));
assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Dcts, false));
assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Dmts, false));
assert!(is_emittable(&ModuleKind::Esm, &MediaType::Tsx, false));
assert!(!is_emittable(
&ModuleKind::Esm,
&MediaType::JavaScript,
false
));
assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Cjs, false));
assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Mjs, false));
assert!(is_emittable(&ModuleKind::Esm, &MediaType::JavaScript, true));
assert!(is_emittable(&ModuleKind::Esm, &MediaType::Jsx, false));
assert!(!is_emittable(&ModuleKind::Esm, &MediaType::Json, false));
} }
} }

View file

@ -48,8 +48,8 @@ pub(crate) fn get_module_graph_error_class(
fn get_resolution_error_class(err: &ResolutionError) -> &'static str { fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
match err { match err {
ResolutionError::ResolverError(err, _, _) => { ResolutionError::ResolverError { error, .. } => {
get_error_class_name(err.as_ref()) get_error_class_name(error.as_ref())
} }
_ => "TypeError", _ => "TypeError",
} }

View file

@ -697,7 +697,11 @@ impl FileFetcher {
} }
pub fn get_local_path(&self, specifier: &ModuleSpecifier) -> Option<PathBuf> { pub fn get_local_path(&self, specifier: &ModuleSpecifier) -> Option<PathBuf> {
if specifier.scheme() == "file" { // TODO(@kitsonk) fix when deno_graph does not query cache for synthetic
// modules
if specifier.scheme() == "flags" {
None
} else if specifier.scheme() == "file" {
specifier.to_file_path().ok() specifier.to_file_path().ok()
} else { } else {
self.http_cache.get_cache_filename(specifier) self.http_cache.get_cache_filename(specifier)

View file

@ -8,17 +8,24 @@ use deno_core::error::AnyError;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::Dependency; use deno_graph::Dependency;
use deno_graph::MediaType; use deno_graph::MediaType;
use deno_graph::Module;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_graph::ModuleGraphError; use deno_graph::ModuleGraphError;
use deno_graph::ModuleKind;
use deno_graph::Range; use deno_graph::Range;
use deno_graph::ResolutionError; use deno_graph::Resolved;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::Arc; use std::sync::Arc;
pub(crate) fn contains_specifier(
v: &[(ModuleSpecifier, ModuleKind)],
specifier: &ModuleSpecifier,
) -> bool {
v.iter().any(|(s, _)| s == specifier)
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub(crate) enum ModuleEntry { pub(crate) enum ModuleEntry {
@ -29,11 +36,10 @@ pub(crate) enum ModuleEntry {
/// A set of type libs that the module has passed a type check with this /// A set of type libs that the module has passed a type check with this
/// session. This would consist of window, worker or both. /// session. This would consist of window, worker or both.
checked_libs: HashSet<TypeLib>, checked_libs: HashSet<TypeLib>,
maybe_types: Option<Result<(ModuleSpecifier, Range), ResolutionError>>, maybe_types: Option<Resolved>,
}, },
Configuration { Configuration {
dependencies: dependencies: BTreeMap<String, Resolved>,
BTreeMap<String, Result<(ModuleSpecifier, Range), ResolutionError>>,
}, },
Error(ModuleGraphError), Error(ModuleGraphError),
Redirect(ModuleSpecifier), Redirect(ModuleSpecifier),
@ -62,64 +68,62 @@ impl GraphData {
continue; continue;
} }
match result { match result {
Ok((_, media_type)) => { Ok((_, _, media_type)) => {
let module = graph.get(&specifier).unwrap(); let module = graph.get(&specifier).unwrap();
let (code, dependencies, maybe_types) = match module { if module.kind == ModuleKind::Synthetic {
Module::Es(es_module) => ( let mut dependencies = BTreeMap::new();
es_module.source.clone(), for (specifier, dependency) in &module.dependencies {
es_module.dependencies.clone(), if !matches!(dependency.maybe_type, Resolved::None) {
es_module dependencies
.maybe_types_dependency .insert(specifier.clone(), dependency.maybe_type.clone());
.as_ref() if let Resolved::Ok {
.and_then(|(_, r)| r.clone()), specifier, range, ..
), } = &dependency.maybe_type
Module::Synthetic(synthetic_module) => match &synthetic_module {
.maybe_source let entry = self.referrer_map.entry(specifier.clone());
{ entry.or_insert_with(|| range.clone());
// Synthetic modules with a source are actually JSON modules.
Some(source) => (source.clone(), Default::default(), None),
// Synthetic modules without a source are config roots.
None => {
let mut dependencies = BTreeMap::new();
for (specifier, resolved) in &synthetic_module.dependencies {
if let Some(dep_result) = resolved {
dependencies.insert(specifier.clone(), dep_result.clone());
if let Ok((specifier, referrer_range)) = dep_result {
let entry = self.referrer_map.entry(specifier.clone());
entry.or_insert_with(|| referrer_range.clone());
}
}
} }
self.modules.insert(
synthetic_module.specifier.clone(),
ModuleEntry::Configuration { dependencies },
);
self
.configurations
.insert(synthetic_module.specifier.clone());
continue;
} }
}, }
self.modules.insert(
module.specifier.clone(),
ModuleEntry::Configuration { dependencies },
);
self.configurations.insert(module.specifier.clone());
}
let code = match &module.maybe_source {
Some(source) => source.clone(),
None => continue,
}; };
if let Some(Ok((specifier, referrer_range))) = &maybe_types { let maybe_types = module
.maybe_types_dependency
.as_ref()
.map(|(_, r)| r.clone());
if let Some(Resolved::Ok {
specifier, range, ..
}) = &maybe_types
{
let specifier = graph.redirects.get(specifier).unwrap_or(specifier); let specifier = graph.redirects.get(specifier).unwrap_or(specifier);
let entry = self.referrer_map.entry(specifier.clone()); let entry = self.referrer_map.entry(specifier.clone());
entry.or_insert_with(|| referrer_range.clone()); entry.or_insert_with(|| range.clone());
} }
for dep in dependencies.values() { for dep in module.dependencies.values() {
#[allow(clippy::manual_flatten)] #[allow(clippy::manual_flatten)]
for resolved in [&dep.maybe_code, &dep.maybe_type] { for resolved in [&dep.maybe_code, &dep.maybe_type] {
if let Some(Ok((specifier, referrer_range))) = resolved { if let Resolved::Ok {
specifier, range, ..
} = resolved
{
let specifier = let specifier =
graph.redirects.get(specifier).unwrap_or(specifier); graph.redirects.get(specifier).unwrap_or(specifier);
let entry = self.referrer_map.entry(specifier.clone()); let entry = self.referrer_map.entry(specifier.clone());
entry.or_insert_with(|| referrer_range.clone()); entry.or_insert_with(|| range.clone());
} }
} }
} }
let module_entry = ModuleEntry::Module { let module_entry = ModuleEntry::Module {
code, code,
dependencies, dependencies: module.dependencies.clone(),
media_type, media_type,
checked_libs: Default::default(), checked_libs: Default::default(),
maybe_types, maybe_types,
@ -142,7 +146,7 @@ impl GraphData {
/// Return `None` if any modules are not known. /// Return `None` if any modules are not known.
pub(crate) fn walk<'a>( pub(crate) fn walk<'a>(
&'a self, &'a self,
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
follow_dynamic: bool, follow_dynamic: bool,
follow_type_only: bool, follow_type_only: bool,
check_js: bool, check_js: bool,
@ -150,7 +154,7 @@ impl GraphData {
let mut result = HashMap::<&'a ModuleSpecifier, &'a ModuleEntry>::new(); let mut result = HashMap::<&'a ModuleSpecifier, &'a ModuleEntry>::new();
let mut seen = HashSet::<&ModuleSpecifier>::new(); let mut seen = HashSet::<&ModuleSpecifier>::new();
let mut visiting = VecDeque::<&ModuleSpecifier>::new(); let mut visiting = VecDeque::<&ModuleSpecifier>::new();
for root in roots { for (root, _) in roots {
seen.insert(root); seen.insert(root);
visiting.push_back(root); visiting.push_back(root);
} }
@ -181,10 +185,10 @@ impl GraphData {
)) ))
&& follow_type_only; && follow_type_only;
if check_types { if check_types {
if let Some(Ok((types, _))) = maybe_types { if let Some(Resolved::Ok { specifier, .. }) = maybe_types {
if !seen.contains(types) { if !seen.contains(specifier) {
seen.insert(types); seen.insert(specifier);
visiting.push_front(types); visiting.push_front(specifier);
} }
} }
} }
@ -196,10 +200,10 @@ impl GraphData {
} }
#[allow(clippy::manual_flatten)] #[allow(clippy::manual_flatten)]
for resolved in resolutions { for resolved in resolutions {
if let Some(Ok((dep_specifier, _))) = resolved { if let Resolved::Ok { specifier, .. } = resolved {
if !seen.contains(dep_specifier) { if !seen.contains(specifier) {
seen.insert(dep_specifier); seen.insert(specifier);
visiting.push_front(dep_specifier); visiting.push_front(specifier);
} }
} }
} }
@ -207,10 +211,12 @@ impl GraphData {
} }
} }
ModuleEntry::Configuration { dependencies } => { ModuleEntry::Configuration { dependencies } => {
for (dep_specifier, _) in dependencies.values().flatten() { for resolved in dependencies.values() {
if !seen.contains(dep_specifier) { if let Resolved::Ok { specifier, .. } = resolved {
seen.insert(dep_specifier); if !seen.contains(specifier) {
visiting.push_front(dep_specifier); seen.insert(specifier);
visiting.push_front(specifier);
}
} }
} }
} }
@ -230,7 +236,7 @@ impl GraphData {
/// `roots`. Returns `None` if any roots are not known. /// `roots`. Returns `None` if any roots are not known.
pub(crate) fn graph_segment( pub(crate) fn graph_segment(
&self, &self,
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
) -> Option<Self> { ) -> Option<Self> {
let mut modules = HashMap::new(); let mut modules = HashMap::new();
let mut referrer_map = HashMap::new(); let mut referrer_map = HashMap::new();
@ -257,7 +263,7 @@ impl GraphData {
/// not known. /// not known.
pub(crate) fn check( pub(crate) fn check(
&self, &self,
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
follow_type_only: bool, follow_type_only: bool,
check_js: bool, check_js: bool,
) -> Option<Result<(), AnyError>> { ) -> Option<Result<(), AnyError>> {
@ -283,7 +289,7 @@ impl GraphData {
)) ))
&& follow_type_only; && follow_type_only;
if check_types { if check_types {
if let Some(Err(error)) = maybe_types { if let Some(Resolved::Err(error)) = maybe_types {
let range = error.range(); let range = error.range();
if !range.specifier.as_str().contains("$deno") { if !range.specifier.as_str().contains("$deno") {
return Some(Err(custom_error( return Some(Err(custom_error(
@ -302,7 +308,7 @@ impl GraphData {
} }
#[allow(clippy::manual_flatten)] #[allow(clippy::manual_flatten)]
for resolved in resolutions { for resolved in resolutions {
if let Some(Err(error)) = resolved { if let Resolved::Err(error) = resolved {
let range = error.range(); let range = error.range();
if !range.specifier.as_str().contains("$deno") { if !range.specifier.as_str().contains("$deno") {
return Some(Err(custom_error( return Some(Err(custom_error(
@ -318,7 +324,7 @@ impl GraphData {
} }
ModuleEntry::Configuration { dependencies } => { ModuleEntry::Configuration { dependencies } => {
for resolved_result in dependencies.values() { for resolved_result in dependencies.values() {
if let Err(error) = resolved_result { if let Resolved::Err(error) = resolved_result {
let range = error.range(); let range = error.range();
if !range.specifier.as_str().contains("$deno") { if !range.specifier.as_str().contains("$deno") {
return Some(Err(custom_error( return Some(Err(custom_error(
@ -331,7 +337,7 @@ impl GraphData {
} }
} }
ModuleEntry::Error(error) => { ModuleEntry::Error(error) => {
if !roots.contains(specifier) { if !contains_specifier(roots, specifier) {
if let Some(range) = self.referrer_map.get(specifier) { if let Some(range) = self.referrer_map.get(specifier) {
if !range.specifier.as_str().contains("$deno") { if !range.specifier.as_str().contains("$deno") {
let message = error.to_string(); let message = error.to_string();
@ -354,7 +360,7 @@ impl GraphData {
/// Assumes that all of those modules are known. /// Assumes that all of those modules are known.
pub(crate) fn set_type_checked( pub(crate) fn set_type_checked(
&mut self, &mut self,
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
lib: &TypeLib, lib: &TypeLib,
) { ) {
let specifiers: Vec<ModuleSpecifier> = let specifiers: Vec<ModuleSpecifier> =
@ -374,10 +380,10 @@ impl GraphData {
/// Check if `roots` are all marked as type checked under `lib`. /// Check if `roots` are all marked as type checked under `lib`.
pub(crate) fn is_type_checked( pub(crate) fn is_type_checked(
&self, &self,
roots: &[ModuleSpecifier], roots: &[(ModuleSpecifier, ModuleKind)],
lib: &TypeLib, lib: &TypeLib,
) -> bool { ) -> bool {
roots.iter().all(|r| { roots.iter().all(|(r, _)| {
let found = self.follow_redirect(r); let found = self.follow_redirect(r);
match self.modules.get(&found) { match self.modules.get(&found) {
Some(ModuleEntry::Module { checked_libs, .. }) => { Some(ModuleEntry::Module { checked_libs, .. }) => {

View file

@ -21,7 +21,10 @@ use std::thread;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio::sync::oneshot; use tokio::sync::oneshot;
type Request = (Vec<ModuleSpecifier>, oneshot::Sender<Result<(), AnyError>>); type Request = (
Vec<(ModuleSpecifier, deno_graph::ModuleKind)>,
oneshot::Sender<Result<(), AnyError>>,
);
/// A "server" that handles requests from the language server to cache modules /// A "server" that handles requests from the language server to cache modules
/// in its own thread. /// in its own thread.
@ -105,7 +108,7 @@ impl CacheServer {
/// client. /// client.
pub async fn cache( pub async fn cache(
&self, &self,
roots: Vec<ModuleSpecifier>, roots: Vec<(ModuleSpecifier, deno_graph::ModuleKind)>,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {
let (tx, rx) = oneshot::channel::<Result<(), AnyError>>(); let (tx, rx) = oneshot::channel::<Result<(), AnyError>>();
if self.0.send((roots, tx)).is_err() { if self.0.send((roots, tx)).is_err() {

View file

@ -20,6 +20,7 @@ use deno_core::error::AnyError;
use deno_core::resolve_url; use deno_core::resolve_url;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::Resolved;
use deno_runtime::tokio_util::create_basic_runtime; use deno_runtime::tokio_util::create_basic_runtime;
use log::error; use log::error;
use lspower::lsp; use lspower::lsp;
@ -547,13 +548,13 @@ fn resolution_error_as_code(
use deno_graph::SpecifierError; use deno_graph::SpecifierError;
match err { match err {
ResolutionError::InvalidDowngrade(_, _) => { ResolutionError::InvalidDowngrade { .. } => {
lsp::NumberOrString::String("invalid-downgrade".to_string()) lsp::NumberOrString::String("invalid-downgrade".to_string())
} }
ResolutionError::InvalidLocalImport(_, _) => { ResolutionError::InvalidLocalImport { .. } => {
lsp::NumberOrString::String("invalid-local-import".to_string()) lsp::NumberOrString::String("invalid-local-import".to_string())
} }
ResolutionError::InvalidSpecifier(err, _) => match err { ResolutionError::InvalidSpecifier { error, .. } => match error {
SpecifierError::ImportPrefixMissing(_, _) => { SpecifierError::ImportPrefixMissing(_, _) => {
lsp::NumberOrString::String("import-prefix-missing".to_string()) lsp::NumberOrString::String("import-prefix-missing".to_string())
} }
@ -561,7 +562,7 @@ fn resolution_error_as_code(
lsp::NumberOrString::String("invalid-url".to_string()) lsp::NumberOrString::String("invalid-url".to_string())
} }
}, },
ResolutionError::ResolverError(_, _, _) => { ResolutionError::ResolverError { .. } => {
lsp::NumberOrString::String("resolver-error".to_string()) lsp::NumberOrString::String("resolver-error".to_string())
} }
} }
@ -575,7 +576,9 @@ fn diagnose_dependency(
maybe_assert_type: Option<&str>, maybe_assert_type: Option<&str>,
) { ) {
match resolved { match resolved {
Some(Ok((specifier, range))) => { Resolved::Ok {
specifier, range, ..
} => {
if let Some(doc) = documents.get(specifier) { if let Some(doc) = documents.get(specifier) {
if let Some(message) = doc.maybe_warning() { if let Some(message) = doc.maybe_warning() {
diagnostics.push(lsp::Diagnostic { diagnostics.push(lsp::Diagnostic {
@ -633,7 +636,7 @@ fn diagnose_dependency(
}); });
} }
} }
Some(Err(err)) => diagnostics.push(lsp::Diagnostic { Resolved::Err(err) => diagnostics.push(lsp::Diagnostic {
range: documents::to_lsp_range(err.range()), range: documents::to_lsp_range(err.range()),
severity: Some(lsp::DiagnosticSeverity::ERROR), severity: Some(lsp::DiagnosticSeverity::ERROR),
code: Some(resolution_error_as_code(err)), code: Some(resolution_error_as_code(err)),

View file

@ -22,7 +22,9 @@ use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::url; use deno_core::url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::source::ResolveResponse;
use deno_graph::Module; use deno_graph::Module;
use deno_graph::Resolved;
use lspower::lsp; use lspower::lsp;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -213,58 +215,6 @@ impl AssetOrDocument {
} }
} }
// TODO(@kitsonk) expose the synthetic module from deno_graph
#[derive(Debug)]
struct SyntheticModule {
dependencies: BTreeMap<String, deno_graph::Resolved>,
specifier: ModuleSpecifier,
}
impl SyntheticModule {
pub fn new(
specifier: ModuleSpecifier,
dependencies: Vec<(String, Option<lsp::Range>)>,
maybe_resolver: Option<&dyn deno_graph::source::Resolver>,
) -> Self {
let dependencies = dependencies
.iter()
.map(|(dep, maybe_range)| {
let range = to_deno_graph_range(&specifier, maybe_range.as_ref());
let result = if let Some(resolver) = maybe_resolver {
resolver.resolve(dep, &specifier).map_err(|err| {
if let Some(specifier_error) =
err.downcast_ref::<deno_graph::SpecifierError>()
{
deno_graph::ResolutionError::InvalidSpecifier(
specifier_error.clone(),
range.clone(),
)
} else {
deno_graph::ResolutionError::ResolverError(
Arc::new(err),
dep.to_string(),
range.clone(),
)
}
})
} else {
deno_core::resolve_import(dep, specifier.as_str()).map_err(|err| {
deno_graph::ResolutionError::ResolverError(
Arc::new(err.into()),
dep.to_string(),
range.clone(),
)
})
};
(dep.to_string(), Some(result.map(|s| (s, range))))
})
.collect();
Self {
dependencies,
specifier,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct DocumentInner { struct DocumentInner {
/// contains the last-known-good set of dependencies from parsing the module /// contains the last-known-good set of dependencies from parsing the module
@ -274,7 +224,7 @@ struct DocumentInner {
maybe_language_id: Option<LanguageId>, maybe_language_id: Option<LanguageId>,
maybe_lsp_version: Option<i32>, maybe_lsp_version: Option<i32>,
maybe_module: maybe_module:
Option<Result<deno_graph::EsModule, deno_graph::ModuleGraphError>>, Option<Result<deno_graph::Module, deno_graph::ModuleGraphError>>,
maybe_navigation_tree: Option<Arc<tsc::NavigationTree>>, maybe_navigation_tree: Option<Arc<tsc::NavigationTree>>,
maybe_warning: Option<String>, maybe_warning: Option<String>,
specifier: ModuleSpecifier, specifier: ModuleSpecifier,
@ -299,16 +249,14 @@ impl Document {
// we only ever do `Document::new` on on disk resources that are supposed to // we only ever do `Document::new` on on disk resources that are supposed to
// be diagnosable, unlike `Document::open`, so it is safe to unconditionally // be diagnosable, unlike `Document::open`, so it is safe to unconditionally
// parse the module. // parse the module.
let maybe_module = match deno_graph::parse_module( let maybe_module = Some(deno_graph::parse_module(
&specifier, &specifier,
maybe_headers, maybe_headers,
content.clone(), content.clone(),
Some(&deno_graph::ModuleKind::Esm),
maybe_resolver, maybe_resolver,
Some(&parser), Some(&parser),
) { ));
Ok(m) => m.to_maybe_es_module().map(Ok),
Err(err) => Some(Err(err)),
};
let dependencies = if let Some(Ok(module)) = &maybe_module { let dependencies = if let Some(Ok(module)) = &maybe_module {
Arc::new(module.dependencies.clone()) Arc::new(module.dependencies.clone())
} else { } else {
@ -340,16 +288,14 @@ impl Document {
let maybe_headers = language_id.as_headers(); let maybe_headers = language_id.as_headers();
let parser = SourceParser::default(); let parser = SourceParser::default();
let maybe_module = if language_id.is_diagnosable() { let maybe_module = if language_id.is_diagnosable() {
match deno_graph::parse_module( Some(deno_graph::parse_module(
&specifier, &specifier,
maybe_headers, maybe_headers,
content.clone(), content.clone(),
Some(&deno_graph::ModuleKind::Esm),
maybe_resolver, maybe_resolver,
Some(&parser), Some(&parser),
) { ))
Ok(m) => m.to_maybe_es_module().map(Ok),
Err(err) => Some(Err(err)),
}
} else { } else {
None None
}; };
@ -411,16 +357,14 @@ impl Document {
.map(|li| li.as_headers()) .map(|li| li.as_headers())
.flatten(); .flatten();
let parser = SourceParser::default(); let parser = SourceParser::default();
match deno_graph::parse_module( Some(deno_graph::parse_module(
&self.0.specifier, &self.0.specifier,
maybe_headers, maybe_headers,
content.clone(), content.clone(),
Some(&deno_graph::ModuleKind::Esm),
maybe_resolver, maybe_resolver,
Some(&parser), Some(&parser),
) { ))
Ok(m) => m.to_maybe_es_module().map(Ok),
Err(err) => Some(Err(err)),
}
} else { } else {
None None
}; };
@ -504,10 +448,19 @@ impl Document {
} }
pub fn maybe_types_dependency(&self) -> deno_graph::Resolved { pub fn maybe_types_dependency(&self) -> deno_graph::Resolved {
let module_result = self.0.maybe_module.as_ref()?; let module_result = match self.0.maybe_module.as_ref() {
let module = module_result.as_ref().ok()?; Some(module_result) => module_result,
let (_, maybe_dep) = module.maybe_types_dependency.as_ref()?; _ => return deno_graph::Resolved::None,
maybe_dep.clone() };
let module = match module_result.as_ref() {
Ok(module) => module,
Err(_) => return deno_graph::Resolved::None,
};
if let Some((_, maybe_dep)) = module.maybe_types_dependency.as_ref() {
maybe_dep.clone()
} else {
deno_graph::Resolved::None
}
} }
pub fn media_type(&self) -> MediaType { pub fn media_type(&self) -> MediaType {
@ -525,18 +478,18 @@ impl Document {
fn maybe_module( fn maybe_module(
&self, &self,
) -> Option<&Result<deno_graph::EsModule, deno_graph::ModuleGraphError>> { ) -> Option<&Result<deno_graph::Module, deno_graph::ModuleGraphError>> {
self.0.maybe_module.as_ref() self.0.maybe_module.as_ref()
} }
pub fn maybe_parsed_source( pub fn maybe_parsed_source(
&self, &self,
) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> { ) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> {
self.maybe_module().map(|r| { let module_result = self.maybe_module()?;
r.as_ref() match module_result {
.map(|m| m.parsed_source.clone()) Ok(module) => Some(Ok(module.maybe_parsed_source.clone()?)),
.map_err(|err| err.clone()) Err(err) => Some(Err(err.clone())),
}) }
} }
pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> { pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> {
@ -576,14 +529,9 @@ impl Document {
} }
} }
pub(crate) fn to_hover_text( pub(crate) fn to_hover_text(result: &Resolved) -> String {
result: &Result<
(ModuleSpecifier, deno_graph::Range),
deno_graph::ResolutionError,
>,
) -> String {
match result { match result {
Ok((specifier, _)) => match specifier.scheme() { Resolved::Ok { specifier, .. } => match specifier.scheme() {
"data" => "_(a data url)_".to_string(), "data" => "_(a data url)_".to_string(),
"blob" => "_(a blob url)_".to_string(), "blob" => "_(a blob url)_".to_string(),
_ => format!( _ => format!(
@ -593,7 +541,8 @@ pub(crate) fn to_hover_text(
) )
.replace('@', "&#8203;@"), .replace('@', "&#8203;@"),
}, },
Err(_) => "_[errored]_".to_string(), Resolved::Err(_) => "_[errored]_".to_string(),
Resolved::None => "_[missing]_".to_string(),
} }
} }
@ -802,7 +751,7 @@ pub(crate) struct Documents {
file_system_docs: Arc<Mutex<FileSystemDocuments>>, file_system_docs: Arc<Mutex<FileSystemDocuments>>,
/// Any imports to the context supplied by configuration files. This is like /// Any imports to the context supplied by configuration files. This is like
/// the imports into the a module graph in CLI. /// the imports into the a module graph in CLI.
imports: Arc<HashMap<ModuleSpecifier, SyntheticModule>>, imports: Arc<HashMap<ModuleSpecifier, Module>>,
/// The optional import map that should be used when resolving dependencies. /// The optional import map that should be used when resolving dependencies.
maybe_import_map: Option<ImportMapResolver>, maybe_import_map: Option<ImportMapResolver>,
/// The optional JSX resolver, which is used when JSX imports are configured. /// The optional JSX resolver, which is used when JSX imports are configured.
@ -913,7 +862,7 @@ impl Documents {
) -> bool { ) -> bool {
let maybe_resolver = self.get_maybe_resolver(); let maybe_resolver = self.get_maybe_resolver();
let maybe_specifier = if let Some(resolver) = maybe_resolver { let maybe_specifier = if let Some(resolver) = maybe_resolver {
resolver.resolve(specifier, referrer).ok() resolver.resolve(specifier, referrer).to_result().ok()
} else { } else {
deno_core::resolve_import(specifier, referrer.as_str()).ok() deno_core::resolve_import(specifier, referrer.as_str()).ok()
}; };
@ -1043,14 +992,14 @@ impl Documents {
results.push(None); results.push(None);
} }
} else if let Some(dep) = dependencies.get(&specifier) { } else if let Some(dep) = dependencies.get(&specifier) {
if let Some(Ok((specifier, _))) = &dep.maybe_type { if let Resolved::Ok { specifier, .. } = &dep.maybe_type {
results.push(self.resolve_dependency(specifier)); results.push(self.resolve_dependency(specifier));
} else if let Some(Ok((specifier, _))) = &dep.maybe_code { } else if let Resolved::Ok { specifier, .. } = &dep.maybe_code {
results.push(self.resolve_dependency(specifier)); results.push(self.resolve_dependency(specifier));
} else { } else {
results.push(None); results.push(None);
} }
} else if let Some(Some(Ok((specifier, _)))) = } else if let Some(Resolved::Ok { specifier, .. }) =
self.resolve_imports_dependency(&specifier) self.resolve_imports_dependency(&specifier)
{ {
// clone here to avoid double borrow of self // clone here to avoid double borrow of self
@ -1121,9 +1070,7 @@ impl Documents {
imports imports
.into_iter() .into_iter()
.map(|(referrer, dependencies)| { .map(|(referrer, dependencies)| {
let dependencies = let module = Module::new_from_type_imports(
dependencies.into_iter().map(|s| (s, None)).collect();
let module = SyntheticModule::new(
referrer.clone(), referrer.clone(),
dependencies, dependencies,
self.get_maybe_resolver(), self.get_maybe_resolver(),
@ -1167,7 +1114,9 @@ impl Documents {
.insert(specifier.clone()); .insert(specifier.clone());
} }
} }
if let Some((_, Some(Ok((dep, _))))) = &module.maybe_types_dependency { if let Some((_, Resolved::Ok { specifier: dep, .. })) =
&module.maybe_types_dependency
{
dependents_map dependents_map
.entry(dep.clone()) .entry(dep.clone())
.or_default() .or_default()
@ -1198,12 +1147,10 @@ impl Documents {
.map(|m| { .map(|m| {
m.maybe_types_dependency m.maybe_types_dependency
.as_ref() .as_ref()
.map(|(_, o)| o.as_ref().map(|r| r.as_ref().ok()).flatten()) .map(|(_, resolved)| resolved.clone())
.flatten()
}) })
.flatten() .flatten();
.cloned(); if let Some(Resolved::Ok { specifier, .. }) = maybe_types_dependency {
if let Some((specifier, _)) = maybe_types_dependency {
self.resolve_dependency(&specifier) self.resolve_dependency(&specifier)
} else { } else {
let media_type = doc.media_type(); let media_type = doc.media_type();
@ -1221,7 +1168,7 @@ impl Documents {
for module in self.imports.values() { for module in self.imports.values() {
let maybe_dep = module.dependencies.get(specifier); let maybe_dep = module.dependencies.get(specifier);
if maybe_dep.is_some() { if maybe_dep.is_some() {
return maybe_dep; return maybe_dep.map(|d| &d.maybe_type);
} }
} }
None None

View file

@ -8,6 +8,7 @@ use deno_core::serde_json;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::Resolved;
use import_map::ImportMap; use import_map::ImportMap;
use log::error; use log::error;
use log::info; use log::info;
@ -1058,34 +1059,38 @@ impl Inner {
.get_code() .get_code()
.map(|s| self.documents.get(s)) .map(|s| self.documents.get(s))
.flatten() .flatten()
.map(|d| d.maybe_types_dependency()) .map(|d| d.maybe_types_dependency());
.flatten(); let value = match (dep.maybe_code.is_none(), dep.maybe_type.is_none(), &dep_maybe_types_dependency) {
let value = match (&dep.maybe_code, &dep.maybe_type, &dep_maybe_types_dependency) { (false, false, None) => format!(
(Some(code_dep), Some(type_dep), None) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n", "**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(code_dep), to_hover_text(&dep.maybe_code),
to_hover_text(type_dep) to_hover_text(&dep.maybe_type)
), ),
(Some(code_dep), Some(type_dep), Some(types_dep)) => format!( (false, false, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n**Types**: {}\n**Import Types**: {}\n", "**Resolved Dependency**\n\n**Code**: {}\n**Types**: {}\n**Import Types**: {}\n",
to_hover_text(code_dep), to_hover_text(&dep.maybe_code),
to_hover_text(types_dep), to_hover_text(&dep.maybe_type),
to_hover_text(type_dep)
),
(Some(code_dep), None, None) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n",
to_hover_text(code_dep)
),
(Some(code_dep), None, Some(types_dep)) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(code_dep),
to_hover_text(types_dep) to_hover_text(types_dep)
), ),
(None, Some(type_dep), _) => format!( (false, false, Some(_)) => format!(
"**Resolved Dependency**\n\n**Types**: {}\n", "**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(type_dep) to_hover_text(&dep.maybe_code),
to_hover_text(&dep.maybe_type)
), ),
(None, None, _) => unreachable!("{}", json!(params)), (false, true, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_code),
to_hover_text(types_dep)
),
(false, true, _) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n",
to_hover_text(&dep.maybe_code)
),
(true, false, _) => format!(
"**Resolved Dependency**\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_type)
),
(true, true, _) => unreachable!("{}", json!(params)),
}; };
let value = let value =
if let Some(docs) = self.module_registries.get_hover(&dep).await { if let Some(docs) = self.module_registries.get_hover(&dep).await {
@ -2677,10 +2682,15 @@ impl Inner {
params params
.uris .uris
.iter() .iter()
.map(|t| self.url_map.normalize_url(&t.uri)) .map(|t| {
(
self.url_map.normalize_url(&t.uri),
deno_graph::ModuleKind::Esm,
)
})
.collect() .collect()
} else { } else {
vec![referrer.clone()] vec![(referrer.clone(), deno_graph::ModuleKind::Esm)]
}; };
if self.maybe_cache_server.is_none() { if self.maybe_cache_server.is_none() {

View file

@ -397,7 +397,9 @@ async fn compile_command(
.then(|| { .then(|| {
let root_module = graph.as_ref().modules()[0]; let root_module = graph.as_ref().modules()[0];
match root_module.media_type { match root_module.media_type {
MediaType::JavaScript => Some(Ok(root_module.source.to_string())), MediaType::JavaScript if root_module.maybe_source.is_some() => {
Some(Ok(root_module.maybe_source.clone().unwrap().to_string()))
}
_ => None, _ => None,
} }
}) })
@ -467,7 +469,7 @@ async fn info_command(
.map(|im| im.as_resolver()) .map(|im| im.as_resolver())
}; };
let graph = deno_graph::create_graph( let graph = deno_graph::create_graph(
vec![specifier], vec![(specifier, deno_graph::ModuleKind::Esm)],
false, false,
None, None,
&mut cache, &mut cache,
@ -547,7 +549,7 @@ async fn cache_command(
for file in cache_flags.files { for file in cache_flags.files {
let specifier = resolve_url_or_path(&file)?; let specifier = resolve_url_or_path(&file)?;
ps.prepare_module_load( ps.prepare_module_load(
vec![specifier], vec![(specifier, deno_graph::ModuleKind::Esm)],
false, false,
lib.clone(), lib.clone(),
Permissions::allow_all(), Permissions::allow_all(),
@ -639,7 +641,7 @@ async fn create_graph_and_maybe_check(
}; };
let graph = Arc::new( let graph = Arc::new(
deno_graph::create_graph( deno_graph::create_graph(
vec![root], vec![(root, deno_graph::ModuleKind::Esm)],
false, false,
maybe_imports, maybe_imports,
&mut cache, &mut cache,
@ -707,7 +709,7 @@ fn bundle_module_graph(
ps: &ProcState, ps: &ProcState,
flags: &Flags, flags: &Flags,
) -> Result<(String, Option<String>), AnyError> { ) -> Result<(String, Option<String>), AnyError> {
info!("{} {}", colors::green("Bundle"), graph.roots[0]); info!("{} {}", colors::green("Bundle"), graph.roots[0].0);
let (ts_config, maybe_ignored_options) = emit::get_ts_config( let (ts_config, maybe_ignored_options) = emit::get_ts_config(
emit::ConfigType::Bundle, emit::ConfigType::Bundle,
@ -777,7 +779,7 @@ async fn bundle_command(
.filter_map(|(_, r)| { .filter_map(|(_, r)| {
r.as_ref() r.as_ref()
.ok() .ok()
.map(|(s, _)| s.to_file_path().ok()) .map(|(s, _, _)| s.to_file_path().ok())
.flatten() .flatten()
}) })
.collect(); .collect();
@ -992,7 +994,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
.map(|im| im.as_resolver()) .map(|im| im.as_resolver())
}; };
let graph = deno_graph::create_graph( let graph = deno_graph::create_graph(
vec![main_module.clone()], vec![(main_module.clone(), deno_graph::ModuleKind::Esm)],
false, false,
maybe_imports, maybe_imports,
&mut cache, &mut cache,
@ -1016,7 +1018,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
.filter_map(|(_, r)| { .filter_map(|(_, r)| {
r.as_ref() r.as_ref()
.ok() .ok()
.map(|(s, _)| s.to_file_path().ok()) .map(|(s, _, _)| s.to_file_path().ok())
.flatten() .flatten()
}) })
.collect(); .collect();

View file

@ -108,7 +108,7 @@ impl ModuleLoader for CliModuleLoader {
async move { async move {
ps.prepare_module_load( ps.prepare_module_load(
vec![specifier], vec![(specifier, deno_graph::ModuleKind::Esm)],
is_dynamic, is_dynamic,
lib, lib,
root_permissions, root_permissions,

View file

@ -24,6 +24,7 @@ use deno_core::serde_json::Value;
use deno_core::Extension; use deno_core::Extension;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
use deno_graph::ModuleKind;
use deno_runtime::permissions::Permissions; use deno_runtime::permissions::Permissions;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
@ -207,9 +208,9 @@ async fn op_emit(
.as_ref() .as_ref()
.map(|imr| imr.as_resolver()) .map(|imr| imr.as_resolver())
}; };
let roots = vec![resolve_url_or_path(&root_specifier)?]; let roots = vec![(resolve_url_or_path(&root_specifier)?, ModuleKind::Esm)];
let maybe_imports = let maybe_imports =
to_maybe_imports(&roots[0], args.compiler_options.as_ref()); to_maybe_imports(&roots[0].0, args.compiler_options.as_ref());
let graph = Arc::new( let graph = Arc::new(
deno_graph::create_graph( deno_graph::create_graph(
roots, roots,

View file

@ -23,6 +23,7 @@ use crate::resolver::JsxResolver;
use crate::source_maps::SourceMapGetter; use crate::source_maps::SourceMapGetter;
use crate::version; use crate::version;
use deno_ast::MediaType;
use deno_core::anyhow::anyhow; use deno_core::anyhow::anyhow;
use deno_core::anyhow::Context; use deno_core::anyhow::Context;
use deno_core::error::custom_error; use deno_core::error::custom_error;
@ -41,7 +42,8 @@ use deno_graph::create_graph;
use deno_graph::source::CacheInfo; use deno_graph::source::CacheInfo;
use deno_graph::source::LoadFuture; use deno_graph::source::LoadFuture;
use deno_graph::source::Loader; use deno_graph::source::Loader;
use deno_graph::MediaType; use deno_graph::ModuleKind;
use deno_graph::Resolved;
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_web::BlobStore; use deno_runtime::deno_web::BlobStore;
@ -252,7 +254,7 @@ impl ProcState {
/// emits where necessary or report any module graph / type checking errors. /// emits where necessary or report any module graph / type checking errors.
pub(crate) async fn prepare_module_load( pub(crate) async fn prepare_module_load(
&self, &self,
roots: Vec<ModuleSpecifier>, roots: Vec<(ModuleSpecifier, ModuleKind)>,
is_dynamic: bool, is_dynamic: bool,
lib: emit::TypeLib, lib: emit::TypeLib,
root_permissions: Permissions, root_permissions: Permissions,
@ -262,7 +264,7 @@ impl ProcState {
// TODO(bartlomieju): this is very make-shift, is there an existing API // TODO(bartlomieju): this is very make-shift, is there an existing API
// that we could include it like with "maybe_imports"? // that we could include it like with "maybe_imports"?
let roots = if self.flags.compat { let roots = if self.flags.compat {
let mut r = vec![compat::GLOBAL_URL.clone()]; let mut r = vec![(compat::GLOBAL_URL.clone(), ModuleKind::Esm)];
r.extend(roots); r.extend(roots);
r r
} else { } else {
@ -438,21 +440,21 @@ impl ProcState {
let graph_data = self.graph_data.read(); let graph_data = self.graph_data.read();
let found_referrer = graph_data.follow_redirect(&referrer); let found_referrer = graph_data.follow_redirect(&referrer);
let maybe_resolved = match graph_data.get(&found_referrer) { let maybe_resolved = match graph_data.get(&found_referrer) {
Some(ModuleEntry::Module { dependencies, .. }) => dependencies Some(ModuleEntry::Module { dependencies, .. }) => {
.get(specifier) dependencies.get(specifier).map(|d| &d.maybe_code)
.and_then(|dep| dep.maybe_code.clone()), }
_ => None, _ => None,
}; };
match maybe_resolved { match maybe_resolved {
Some(Ok((specifier, _))) => return Ok(specifier), Some(Resolved::Ok { specifier, .. }) => return Ok(specifier.clone()),
Some(Err(err)) => { Some(Resolved::Err(err)) => {
return Err(custom_error( return Err(custom_error(
"TypeError", "TypeError",
format!("{}\n", err.to_string_with_range()), format!("{}\n", err.to_string_with_range()),
)) ))
} }
None => {} Some(Resolved::None) | None => {}
} }
} }
@ -472,7 +474,7 @@ impl ProcState {
None None
}; };
if let Some(resolver) = &maybe_resolver { if let Some(resolver) = &maybe_resolver {
resolver.resolve(specifier, &referrer) resolver.resolve(specifier, &referrer).to_result()
} else { } else {
deno_core::resolve_import(specifier, referrer.as_str()) deno_core::resolve_import(specifier, referrer.as_str())
.map_err(|err| err.into()) .map_err(|err| err.into())

View file

@ -1,8 +1,8 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError;
use deno_core::resolve_import; use deno_core::resolve_import;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::source::ResolveResponse;
use deno_graph::source::Resolver; use deno_graph::source::Resolver;
use import_map::ImportMap; use import_map::ImportMap;
use std::sync::Arc; use std::sync::Arc;
@ -28,11 +28,11 @@ impl Resolver for ImportMapResolver {
&self, &self,
specifier: &str, specifier: &str,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> { ) -> ResolveResponse {
self match self.0.resolve(specifier, referrer) {
.0 Ok(specifier) => ResolveResponse::Specifier(specifier),
.resolve(specifier, referrer) Err(err) => ResolveResponse::Err(err.into()),
.map_err(|err| err.into()) }
} }
} }
@ -67,9 +67,12 @@ impl Resolver for JsxResolver {
&self, &self,
specifier: &str, specifier: &str,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> { ) -> ResolveResponse {
self.maybe_import_map_resolver.as_ref().map_or_else( self.maybe_import_map_resolver.as_ref().map_or_else(
|| resolve_import(specifier, referrer.as_str()).map_err(|err| err.into()), || match resolve_import(specifier, referrer.as_str()) {
Ok(specifier) => ResolveResponse::Specifier(specifier),
Err(err) => ResolveResponse::Err(err.into()),
},
|r| r.resolve(specifier, referrer), |r| r.resolve(specifier, referrer),
) )
} }

View file

@ -22,10 +22,10 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]005_more_imports.ts", "local": "[WILDCARD]005_more_imports.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/005_more_imports.ts" "specifier": "file://[WILDCARD]/005_more_imports.ts"
}, },
{ {
@ -47,18 +47,17 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]mod1.ts", "local": "[WILDCARD]mod1.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/subdir/mod1.ts" "specifier": "file://[WILDCARD]/subdir/mod1.ts"
}, },
{ {
"dependencies": [], "kind": "esm",
"local": "[WILDCARD]print_hello.ts", "local": "[WILDCARD]print_hello.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/subdir/print_hello.ts" "specifier": "file://[WILDCARD]/subdir/print_hello.ts"
}, },
{ {
@ -80,10 +79,10 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]mod2.ts", "local": "[WILDCARD]mod2.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts" "specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts"
} }
], ],

View file

@ -22,10 +22,10 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]076_info_json_deps_order.ts", "local": "[WILDCARD]076_info_json_deps_order.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/076_info_json_deps_order.ts" "specifier": "file://[WILDCARD]/076_info_json_deps_order.ts"
}, },
{ {
@ -63,10 +63,10 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]A.ts", "local": "[WILDCARD]A.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/recursive_imports/A.ts" "specifier": "file://[WILDCARD]/recursive_imports/A.ts"
}, },
{ {
@ -104,10 +104,10 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]B.ts", "local": "[WILDCARD]B.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/recursive_imports/B.ts" "specifier": "file://[WILDCARD]/recursive_imports/B.ts"
}, },
{ {
@ -145,18 +145,17 @@
} }
} }
], ],
"kind": "esm",
"local": "[WILDCARD]C.ts", "local": "[WILDCARD]C.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/recursive_imports/C.ts" "specifier": "file://[WILDCARD]/recursive_imports/C.ts"
}, },
{ {
"dependencies": [], "kind": "esm",
"local": "[WILDCARD]common.ts", "local": "[WILDCARD]common.ts",
[WILDCARD] [WILDCARD]
"mediaType": "TypeScript", "mediaType": "TypeScript",
[WILDCARD]
"specifier": "file://[WILDCARD]/recursive_imports/common.ts" "specifier": "file://[WILDCARD]/recursive_imports/common.ts"
} }
], ],

View file

@ -18,7 +18,9 @@ use deno_graph::create_graph;
use deno_graph::source::LoadFuture; use deno_graph::source::LoadFuture;
use deno_graph::source::LoadResponse; use deno_graph::source::LoadResponse;
use deno_graph::source::Loader; use deno_graph::source::Loader;
use deno_graph::source::ResolveResponse;
use deno_graph::source::Resolver; use deno_graph::source::Resolver;
use deno_graph::ModuleKind;
use deno_graph::ModuleSpecifier; use deno_graph::ModuleSpecifier;
use deno_runtime::permissions::Permissions; use deno_runtime::permissions::Permissions;
use import_map::ImportMap; use import_map::ImportMap;
@ -47,17 +49,18 @@ impl Resolver for DocResolver {
&self, &self,
specifier: &str, specifier: &str,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> { ) -> ResolveResponse {
if let Some(import_map) = &self.import_map { if let Some(import_map) = &self.import_map {
return import_map return match import_map.resolve(specifier, referrer) {
.resolve(specifier, referrer) Ok(specifier) => ResolveResponse::Specifier(specifier),
.map_err(AnyError::from); Err(err) => ResolveResponse::Err(err.into()),
};
} }
let module_specifier = match deno_core::resolve_import(specifier, referrer.as_str()) {
deno_core::resolve_import(specifier, referrer.as_str())?; Ok(specifier) => ResolveResponse::Specifier(specifier),
Err(err) => ResolveResponse::Err(err.into()),
Ok(module_specifier) }
} }
} }
@ -104,7 +107,7 @@ pub async fn print_docs(
let source_file_specifier = let source_file_specifier =
ModuleSpecifier::parse("deno://lib.deno.d.ts").unwrap(); ModuleSpecifier::parse("deno://lib.deno.d.ts").unwrap();
let graph = create_graph( let graph = create_graph(
vec![source_file_specifier.clone()], vec![(source_file_specifier.clone(), ModuleKind::Esm)],
false, false,
None, None,
&mut loader, &mut loader,
@ -144,7 +147,7 @@ pub async fn print_docs(
import_map: ps.maybe_import_map.clone(), import_map: ps.maybe_import_map.clone(),
}; };
let graph = create_graph( let graph = create_graph(
vec![root_specifier.clone()], vec![(root_specifier.clone(), ModuleKind::Esm)],
false, false,
None, None,
&mut loader, &mut loader,

View file

@ -15,6 +15,7 @@ use crate::flags::TestFlags;
use crate::fs_util::collect_specifiers; use crate::fs_util::collect_specifiers;
use crate::fs_util::is_supported_test_ext; use crate::fs_util::is_supported_test_ext;
use crate::fs_util::is_supported_test_path; use crate::fs_util::is_supported_test_path;
use crate::graph_util::contains_specifier;
use crate::graph_util::graph_valid; use crate::graph_util::graph_valid;
use crate::located_script_name; use crate::located_script_name;
use crate::lockfile; use crate::lockfile;
@ -34,7 +35,7 @@ use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::Module; use deno_graph::ModuleKind;
use deno_runtime::permissions::Permissions; use deno_runtime::permissions::Permissions;
use deno_runtime::tokio_util::run_basic; use deno_runtime::tokio_util::run_basic;
use log::Level; use log::Level;
@ -724,7 +725,7 @@ async fn check_specifiers(
if !inline_files.is_empty() { if !inline_files.is_empty() {
let specifiers = inline_files let specifiers = inline_files
.iter() .iter()
.map(|file| file.specifier.clone()) .map(|file| (file.specifier.clone(), ModuleKind::Esm))
.collect(); .collect();
for file in inline_files { for file in inline_files {
@ -746,7 +747,7 @@ async fn check_specifiers(
.iter() .iter()
.filter_map(|(specifier, mode)| { .filter_map(|(specifier, mode)| {
if *mode != TestMode::Documentation { if *mode != TestMode::Documentation {
Some(specifier.clone()) Some((specifier.clone(), ModuleKind::Esm))
} else { } else {
None None
} }
@ -1113,7 +1114,7 @@ pub async fn run_tests_with_watch(
} else { } else {
test_modules test_modules
.iter() .iter()
.filter_map(|url| deno_core::resolve_url(url.as_str()).ok()) .map(|url| (url.clone(), ModuleKind::Esm))
.collect() .collect()
}; };
let maybe_imports = if let Some(result) = maybe_imports { let maybe_imports = if let Some(result) = maybe_imports {
@ -1129,7 +1130,10 @@ pub async fn run_tests_with_watch(
.map(|im| im.as_resolver()) .map(|im| im.as_resolver())
}; };
let graph = deno_graph::create_graph( let graph = deno_graph::create_graph(
test_modules.clone(), test_modules
.iter()
.map(|s| (s.clone(), ModuleKind::Esm))
.collect(),
false, false,
maybe_imports, maybe_imports,
cache.as_mut_loader(), cache.as_mut_loader(),
@ -1151,7 +1155,7 @@ pub async fn run_tests_with_watch(
output: &mut HashSet<&'a ModuleSpecifier>, output: &mut HashSet<&'a ModuleSpecifier>,
no_check: bool, no_check: bool,
) { ) {
if let Some(Module::Es(module)) = maybe_module { if let Some(module) = maybe_module {
for dep in module.dependencies.values() { for dep in module.dependencies.values() {
if let Some(specifier) = &dep.get_code() { if let Some(specifier) = &dep.get_code() {
if !output.contains(specifier) { if !output.contains(specifier) {
@ -1197,7 +1201,7 @@ pub async fn run_tests_with_watch(
deno_core::resolve_url_or_path(&path.to_string_lossy()).ok() deno_core::resolve_url_or_path(&path.to_string_lossy()).ok()
}) { }) {
if modules.contains(&&path) { if modules.contains(&&path) {
modules_to_reload.push(specifier); modules_to_reload.push((specifier, ModuleKind::Esm));
break; break;
} }
} }
@ -1228,7 +1232,7 @@ pub async fn run_tests_with_watch(
}) })
}; };
let operation = |modules_to_reload: Vec<ModuleSpecifier>| { let operation = |modules_to_reload: Vec<(ModuleSpecifier, ModuleKind)>| {
let filter = test_flags.filter.clone(); let filter = test_flags.filter.clone();
let include = include.clone(); let include = include.clone();
let ignore = ignore.clone(); let ignore = ignore.clone();
@ -1245,7 +1249,9 @@ pub async fn run_tests_with_watch(
) )
.await? .await?
.iter() .iter()
.filter(|(specifier, _)| modules_to_reload.contains(specifier)) .filter(|(specifier, _)| {
contains_specifier(&modules_to_reload, specifier)
})
.cloned() .cloned()
.collect::<Vec<(ModuleSpecifier, TestMode)>>(); .collect::<Vec<(ModuleSpecifier, TestMode)>>();

View file

@ -25,6 +25,7 @@ use deno_core::ModuleSpecifier;
use deno_core::OpFn; use deno_core::OpFn;
use deno_core::RuntimeOptions; use deno_core::RuntimeOptions;
use deno_core::Snapshot; use deno_core::Snapshot;
use deno_graph::Resolved;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
@ -513,8 +514,12 @@ fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
let referrer = graph_data.follow_redirect(&referrer); let referrer = graph_data.follow_redirect(&referrer);
let resolved_dep = match graph_data.get(&referrer) { let resolved_dep = match graph_data.get(&referrer) {
Some(ModuleEntry::Module { dependencies, .. }) => { Some(ModuleEntry::Module { dependencies, .. }) => {
dependencies.get(specifier).and_then(|d| { dependencies.get(specifier).map(|d| {
d.maybe_type.as_ref().or_else(|| d.maybe_code.as_ref()) if matches!(d.maybe_type, Resolved::Ok { .. }) {
&d.maybe_type
} else {
&d.maybe_code
}
}) })
} }
Some(ModuleEntry::Configuration { dependencies }) => { Some(ModuleEntry::Configuration { dependencies }) => {
@ -523,7 +528,7 @@ fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
_ => None, _ => None,
}; };
let maybe_result = match resolved_dep { let maybe_result = match resolved_dep {
Some(Ok((specifier, _))) => { Some(Resolved::Ok { specifier, .. }) => {
let specifier = graph_data.follow_redirect(specifier); let specifier = graph_data.follow_redirect(specifier);
match graph_data.get(&specifier) { match graph_data.get(&specifier) {
Some(ModuleEntry::Module { Some(ModuleEntry::Module {
@ -531,8 +536,8 @@ fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
maybe_types, maybe_types,
.. ..
}) => match maybe_types { }) => match maybe_types {
Some(Ok((types, _))) => { Some(Resolved::Ok { specifier, .. }) => {
let types = graph_data.follow_redirect(types); let types = graph_data.follow_redirect(specifier);
match graph_data.get(&types) { match graph_data.get(&types) {
Some(ModuleEntry::Module { media_type, .. }) => { Some(ModuleEntry::Module { media_type, .. }) => {
Some((types, media_type)) Some((types, media_type))
@ -698,6 +703,7 @@ mod tests {
use crate::diagnostics::DiagnosticCategory; use crate::diagnostics::DiagnosticCategory;
use crate::emit::Stats; use crate::emit::Stats;
use deno_core::futures::future; use deno_core::futures::future;
use deno_graph::ModuleKind;
use std::fs; use std::fs;
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -741,7 +747,7 @@ mod tests {
let fixtures = test_util::testdata_path().join("tsc2"); let fixtures = test_util::testdata_path().join("tsc2");
let mut loader = MockLoader { fixtures }; let mut loader = MockLoader { fixtures };
let graph = deno_graph::create_graph( let graph = deno_graph::create_graph(
vec![specifier], vec![(specifier, ModuleKind::Esm)],
false, false,
None, None,
&mut loader, &mut loader,
@ -768,7 +774,7 @@ mod tests {
let fixtures = test_util::testdata_path().join("tsc2"); let fixtures = test_util::testdata_path().join("tsc2");
let mut loader = MockLoader { fixtures }; let mut loader = MockLoader { fixtures };
let graph = deno_graph::create_graph( let graph = deno_graph::create_graph(
vec![specifier.clone()], vec![(specifier.clone(), ModuleKind::Esm)],
false, false,
None, None,
&mut loader, &mut loader,