mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 00:29:09 -05:00
refactor: integrate deno_graph breaking changes (#13495)
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
parent
5490cfed20
commit
7d356250e8
21 changed files with 433 additions and 359 deletions
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -115,9 +115,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.52"
|
||||
version = "1.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
|
||||
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
|
@ -720,7 +720,7 @@ dependencies = [
|
|||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
"data-url",
|
||||
"deno_ast",
|
||||
"deno_ast 0.10.0",
|
||||
"deno_bench_util",
|
||||
"deno_broadcast_channel",
|
||||
"deno_console",
|
||||
|
@ -790,6 +790,23 @@ name = "deno_ast"
|
|||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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 = [
|
||||
"anyhow",
|
||||
"base64 0.13.0",
|
||||
|
@ -835,7 +852,7 @@ name = "deno_core"
|
|||
version = "0.117.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
"deno_ast 0.9.0",
|
||||
"futures",
|
||||
"indexmap",
|
||||
"libc",
|
||||
|
@ -882,12 +899,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_doc"
|
||||
version = "0.26.1"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e82f45d6513b789c04adf0915ca3c3c696f5f5f9379a82834ad4f783fbaa8b3a"
|
||||
checksum = "a37040708cc0c8f1f826073774ea4406bee735d8cb6aacd0b9891e27be7c13bd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"deno_ast",
|
||||
"deno_ast 0.10.0",
|
||||
"deno_graph",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
|
@ -928,14 +945,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.18.0"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b2a21feedd2fde8846a8b94855498ff7e1c59bdf972a06a6faf228999c1f7fd"
|
||||
checksum = "86eccec721ae9dceae2e6cbd83b63de3ef810e7c39357c9a867c98b9633d4775"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if 1.0.0",
|
||||
"data-url",
|
||||
"deno_ast",
|
||||
"deno_ast 0.10.0",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
|
@ -964,12 +981,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_lint"
|
||||
version = "0.22.0"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cf1715d924e6fdf45847868b31742ed305fb6270747c6046dc3c19f67c0d2f5"
|
||||
checksum = "c838bbcaffd4143940068bea8eb5faa6de1ed8c3d3d0a63d8ed7319a967f47bd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
"deno_ast 0.10.0",
|
||||
"derive_more",
|
||||
"if_chain",
|
||||
"log",
|
||||
|
@ -1204,9 +1221,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-core"
|
||||
version = "0.49.0"
|
||||
version = "0.49.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8113ac9998173de8fa4fcf6fc7fe80c15c93df290828afa060dbdbb84337afbf"
|
||||
checksum = "50bcbca32c5b922a8b4ededae420ca17aa7c1ac03131bebe7f78d682945e21a1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bumpalo",
|
||||
|
@ -1241,12 +1258,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.62.0"
|
||||
version = "0.62.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3e9b87d22638bc08075c827ae568e02b07fbf262142db90895383bac3f5a67e"
|
||||
checksum = "312bd921ea751a303703123e2e26e28456abd6ae9ff42dce478e16f613154874"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
"deno_ast 0.10.0",
|
||||
"dprint-core",
|
||||
"parking_lot_core",
|
||||
"rustc-hash",
|
||||
|
|
|
@ -45,11 +45,11 @@ winapi = "=0.3.9"
|
|||
winres = "=0.1.11"
|
||||
|
||||
[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_doc = "0.26.0"
|
||||
deno_graph = "0.18.0"
|
||||
deno_lint = { version = "0.22.0", features = ["docs"] }
|
||||
deno_doc = "0.28.0"
|
||||
deno_graph = "0.21.1"
|
||||
deno_lint = { version = "0.23.0", features = ["docs"] }
|
||||
deno_runtime = { version = "0.43.0", path = "../runtime" }
|
||||
|
||||
atty = "=0.2.14"
|
||||
|
@ -63,7 +63,7 @@ data-url = "=0.1.1"
|
|||
dissimilar = "=1.0.2"
|
||||
dprint-plugin-json = "=0.14.0"
|
||||
dprint-plugin-markdown = "=0.12.1"
|
||||
dprint-plugin-typescript = "=0.62.0"
|
||||
dprint-plugin-typescript = "=0.62.1"
|
||||
encoding_rs = "=0.8.29"
|
||||
env_logger = "=0.8.4"
|
||||
fancy-regex = "=0.7.1"
|
||||
|
|
|
@ -9,6 +9,7 @@ use deno_core::serde_json::Map;
|
|||
use deno_core::serde_json::Value;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::ResolveResponse;
|
||||
use deno_graph::source::Resolver;
|
||||
use regex::Regex;
|
||||
use std::path::PathBuf;
|
||||
|
@ -31,24 +32,28 @@ impl Resolver for NodeEsmResolver {
|
|||
&self,
|
||||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> ResolveResponse {
|
||||
// First try to resolve using import map, ignoring any errors
|
||||
if !specifier.starts_with("node:") {
|
||||
if let Some(import_map_resolver) = &self.maybe_import_map_resolver {
|
||||
if let Ok(specifier) = import_map_resolver.resolve(specifier, referrer)
|
||||
{
|
||||
return Ok(specifier);
|
||||
let response = import_map_resolver.resolve(specifier, referrer);
|
||||
if !matches!(response, ResolveResponse::Err(_)) {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let current_dir = match std::env::current_dir() {
|
||||
Ok(path) => path,
|
||||
Err(err) => return ResolveResponse::Err(err.into()),
|
||||
};
|
||||
let node_resolution =
|
||||
node_resolve(specifier, referrer.as_str(), &std::env::current_dir()?);
|
||||
node_resolve(specifier, referrer.as_str(), ¤t_dir);
|
||||
|
||||
match node_resolution {
|
||||
Ok(specifier) => {
|
||||
Ok(resolve_response) => {
|
||||
// If node resolution succeeded, return the specifier
|
||||
Ok(specifier)
|
||||
resolve_response
|
||||
}
|
||||
Err(err) => {
|
||||
// If node resolution failed, check if it's because of unsupported
|
||||
|
@ -57,11 +62,13 @@ impl Resolver for NodeEsmResolver {
|
|||
.to_string()
|
||||
.starts_with("[ERR_UNSUPPORTED_ESM_URL_SCHEME]")
|
||||
{
|
||||
return deno_core::resolve_import(specifier, referrer.as_str())
|
||||
.map_err(|err| err.into());
|
||||
return match deno_core::resolve_import(specifier, referrer.as_str()) {
|
||||
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,
|
||||
referrer: &str,
|
||||
cwd: &std::path::Path,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ResolveResponse, AnyError> {
|
||||
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
|
||||
|
||||
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 url.scheme() == "data" {
|
||||
return Ok(url);
|
||||
return Ok(ResolveResponse::Specifier(url));
|
||||
}
|
||||
|
||||
let protocol = url.scheme();
|
||||
|
@ -95,7 +102,7 @@ fn node_resolve(
|
|||
if let Some(resolved) =
|
||||
crate::compat::try_resolve_builtin_module(&specifier)
|
||||
{
|
||||
return Ok(resolved);
|
||||
return Ok(ResolveResponse::Esm(resolved));
|
||||
} else {
|
||||
return Err(generic_error(format!("Unknown module {}", specifier)));
|
||||
}
|
||||
|
@ -107,7 +114,8 @@ fn node_resolve(
|
|||
|
||||
if referrer.starts_with("data:") {
|
||||
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 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
|
||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||
Ok(url)
|
||||
Ok(resolve_response)
|
||||
}
|
||||
|
||||
fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
|
||||
|
@ -1146,7 +1168,8 @@ mod tests {
|
|||
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
|
||||
let expected =
|
||||
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(
|
||||
"data:application/javascript,console.log(\"Hello%20Deno\");",
|
||||
|
@ -1154,12 +1177,11 @@ mod tests {
|
|||
&cwd,
|
||||
)
|
||||
.unwrap();
|
||||
eprintln!("actual {}", actual);
|
||||
assert_eq!(
|
||||
actual,
|
||||
let expected =
|
||||
Url::parse("data:application/javascript,console.log(\"Hello%20Deno\");")
|
||||
.unwrap()
|
||||
);
|
||||
.unwrap();
|
||||
assert!(matches!(actual, ResolveResponse::Specifier(_)));
|
||||
assert_eq!(actual.to_result().unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1169,7 +1191,8 @@ mod tests {
|
|||
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
|
||||
let expected =
|
||||
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]
|
||||
|
@ -1179,13 +1202,15 @@ mod tests {
|
|||
let actual = node_resolve("foo", main.as_str(), &cwd).unwrap();
|
||||
let foo_js =
|
||||
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 bar_js =
|
||||
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]
|
||||
|
@ -1196,12 +1221,12 @@ mod tests {
|
|||
Url::parse("https://deno.land/std@0.123.0/node/http.ts").unwrap();
|
||||
|
||||
let actual = node_resolve("http", main.as_str(), &cwd).unwrap();
|
||||
println!("actual {}", actual);
|
||||
assert_eq!(actual, expected);
|
||||
assert!(matches!(actual, ResolveResponse::Esm(_)));
|
||||
assert_eq!(actual.to_result().unwrap(), expected);
|
||||
|
||||
let actual = node_resolve("node:http", main.as_str(), &cwd).unwrap();
|
||||
println!("actual {}", actual);
|
||||
assert_eq!(actual, expected);
|
||||
assert!(matches!(actual, ResolveResponse::Esm(_)));
|
||||
assert_eq!(actual.to_result().unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1214,14 +1239,16 @@ mod tests {
|
|||
cwd.join("node_modules/imports_exports/import_export.js"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
assert!(matches!(actual, ResolveResponse::CommonJs(_)));
|
||||
assert_eq!(actual.to_result().unwrap(), expected);
|
||||
|
||||
// check that `imports` mapping works correctly
|
||||
let cwd = testdir("conditions/node_modules/imports_exports");
|
||||
let main = Url::from_file_path(cwd.join("import_export.js")).unwrap();
|
||||
let actual = node_resolve("#dep", main.as_str(), &cwd).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]
|
||||
|
|
98
cli/emit.rs
98
cli/emit.rs
|
@ -49,6 +49,7 @@ use deno_core::ModuleSpecifier;
|
|||
use deno_graph::MediaType;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_graph::ResolutionError;
|
||||
use std::collections::HashMap;
|
||||
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
|
||||
/// emitted, otherwise they would be ignored if only imported into JavaScript.
|
||||
fn get_tsc_roots(
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
graph_data: &GraphData,
|
||||
check_js: bool,
|
||||
) -> Vec<(ModuleSpecifier, MediaType)> {
|
||||
|
@ -292,7 +293,7 @@ fn get_tsc_roots(
|
|||
} else {
|
||||
roots
|
||||
.iter()
|
||||
.filter_map(|specifier| match graph_data.get(specifier) {
|
||||
.filter_map(|(specifier, _)| match graph_data.get(specifier) {
|
||||
Some(ModuleEntry::Module { 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.
|
||||
pub(crate) fn is_emittable(media_type: &MediaType, include_js: bool) -> bool {
|
||||
/// Determine if a given module kind and media type is emittable or not.
|
||||
pub(crate) fn is_emittable(
|
||||
kind: &ModuleKind,
|
||||
media_type: &MediaType,
|
||||
include_js: bool,
|
||||
) -> bool {
|
||||
if matches!(kind, ModuleKind::Synthetic) {
|
||||
return false;
|
||||
}
|
||||
match &media_type {
|
||||
MediaType::TypeScript
|
||||
| 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
|
||||
/// before the function is called.
|
||||
pub(crate) fn check_and_maybe_emit(
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
graph_data: Arc<RwLock<GraphData>>,
|
||||
cache: &mut dyn Cacher,
|
||||
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);
|
||||
if options.log_checks {
|
||||
for root in roots {
|
||||
for (root, _) in roots {
|
||||
let root_str = root.to_string();
|
||||
// `$deno` specifiers are internal, don't print them.
|
||||
if !root_str.contains("$deno") {
|
||||
|
@ -401,7 +409,7 @@ pub(crate) fn check_and_maybe_emit(
|
|||
let maybe_tsbuildinfo = if options.reload {
|
||||
None
|
||||
} 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
|
||||
// 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 {
|
||||
// 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
|
||||
for root in roots {
|
||||
for (root, _) in roots {
|
||||
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) {
|
||||
let (fm, module) = transpile_module(
|
||||
specifier,
|
||||
m.maybe_source().unwrap_or(""),
|
||||
*m.media_type(),
|
||||
m.maybe_source.as_ref().map(|s| s.as_str()).unwrap_or(""),
|
||||
m.media_type,
|
||||
self.emit_options,
|
||||
self.cm.clone(),
|
||||
)?;
|
||||
|
@ -716,7 +724,7 @@ pub(crate) fn bundle(
|
|||
let mut entries = HashMap::new();
|
||||
entries.insert(
|
||||
"bundle".to_string(),
|
||||
swc::common::FileName::Url(graph.roots[0].clone()),
|
||||
swc::common::FileName::Url(graph.roots[0].0.clone()),
|
||||
);
|
||||
let output = bundler
|
||||
.bundle(entries)
|
||||
|
@ -795,21 +803,32 @@ pub(crate) fn emit(
|
|||
let mut file_count = 0_u32;
|
||||
for module in graph.modules() {
|
||||
file_count += 1;
|
||||
if !is_emittable(&module.media_type, include_js) {
|
||||
if !is_emittable(&module.kind, &module.media_type, include_js) {
|
||||
continue;
|
||||
}
|
||||
let needs_reload =
|
||||
options.reload && !options.reload_exclusions.contains(&module.specifier);
|
||||
let version = get_version(module.source.as_bytes(), &config_bytes);
|
||||
let is_valid = cache
|
||||
let version = get_version(
|
||||
module.maybe_source.as_ref().map(|s| s.as_bytes()).unwrap(),
|
||||
&config_bytes,
|
||||
);
|
||||
let is_valid =
|
||||
cache
|
||||
.get(CacheType::Version, &module.specifier)
|
||||
.map_or(false, |v| {
|
||||
v == get_version(module.source.as_bytes(), &config_bytes)
|
||||
v == get_version(
|
||||
module.maybe_source.as_ref().map(|s| s.as_bytes()).unwrap(),
|
||||
&config_bytes,
|
||||
)
|
||||
});
|
||||
if is_valid && !needs_reload {
|
||||
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;
|
||||
cache.set(CacheType::Emit, &module.specifier, transpiled_source.text)?;
|
||||
if let Some(map) = transpiled_source.source_map {
|
||||
|
@ -897,8 +916,8 @@ impl fmt::Display for GraphError {
|
|||
ModuleGraphError::ResolutionError(err) => {
|
||||
if matches!(
|
||||
err,
|
||||
ResolutionError::InvalidDowngrade(_, _)
|
||||
| ResolutionError::InvalidLocalImport(_, _)
|
||||
ResolutionError::InvalidDowngrade { .. }
|
||||
| ResolutionError::InvalidLocalImport { .. }
|
||||
) {
|
||||
write!(f, "{}", err.to_string_with_range())
|
||||
} else {
|
||||
|
@ -918,7 +937,7 @@ pub(crate) fn to_file_map(
|
|||
) -> HashMap<String, String> {
|
||||
let mut files = HashMap::new();
|
||||
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) {
|
||||
files.insert(format!("{}.js", specifier), emit);
|
||||
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) {
|
||||
files.insert(
|
||||
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]
|
||||
fn test_is_emittable() {
|
||||
assert!(is_emittable(&MediaType::TypeScript, false));
|
||||
assert!(!is_emittable(&MediaType::Dts, false));
|
||||
assert!(!is_emittable(&MediaType::Dcts, false));
|
||||
assert!(!is_emittable(&MediaType::Dmts, false));
|
||||
assert!(is_emittable(&MediaType::Tsx, false));
|
||||
assert!(!is_emittable(&MediaType::JavaScript, false));
|
||||
assert!(!is_emittable(&MediaType::Cjs, false));
|
||||
assert!(!is_emittable(&MediaType::Mjs, false));
|
||||
assert!(is_emittable(&MediaType::JavaScript, true));
|
||||
assert!(is_emittable(&MediaType::Jsx, false));
|
||||
assert!(!is_emittable(&MediaType::Json, false));
|
||||
assert!(is_emittable(
|
||||
&ModuleKind::Esm,
|
||||
&MediaType::TypeScript,
|
||||
false
|
||||
));
|
||||
assert!(!is_emittable(
|
||||
&ModuleKind::Synthetic,
|
||||
&MediaType::TypeScript,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ pub(crate) fn get_module_graph_error_class(
|
|||
|
||||
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
||||
match err {
|
||||
ResolutionError::ResolverError(err, _, _) => {
|
||||
get_error_class_name(err.as_ref())
|
||||
ResolutionError::ResolverError { error, .. } => {
|
||||
get_error_class_name(error.as_ref())
|
||||
}
|
||||
_ => "TypeError",
|
||||
}
|
||||
|
|
|
@ -697,7 +697,11 @@ impl FileFetcher {
|
|||
}
|
||||
|
||||
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()
|
||||
} else {
|
||||
self.http_cache.get_cache_filename(specifier)
|
||||
|
|
|
@ -8,17 +8,24 @@ use deno_core::error::AnyError;
|
|||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Dependency;
|
||||
use deno_graph::MediaType;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_graph::Range;
|
||||
use deno_graph::ResolutionError;
|
||||
use deno_graph::Resolved;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) fn contains_specifier(
|
||||
v: &[(ModuleSpecifier, ModuleKind)],
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> bool {
|
||||
v.iter().any(|(s, _)| s == specifier)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
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
|
||||
/// session. This would consist of window, worker or both.
|
||||
checked_libs: HashSet<TypeLib>,
|
||||
maybe_types: Option<Result<(ModuleSpecifier, Range), ResolutionError>>,
|
||||
maybe_types: Option<Resolved>,
|
||||
},
|
||||
Configuration {
|
||||
dependencies:
|
||||
BTreeMap<String, Result<(ModuleSpecifier, Range), ResolutionError>>,
|
||||
dependencies: BTreeMap<String, Resolved>,
|
||||
},
|
||||
Error(ModuleGraphError),
|
||||
Redirect(ModuleSpecifier),
|
||||
|
@ -62,64 +68,62 @@ impl GraphData {
|
|||
continue;
|
||||
}
|
||||
match result {
|
||||
Ok((_, media_type)) => {
|
||||
Ok((_, _, media_type)) => {
|
||||
let module = graph.get(&specifier).unwrap();
|
||||
let (code, dependencies, maybe_types) = match module {
|
||||
Module::Es(es_module) => (
|
||||
es_module.source.clone(),
|
||||
es_module.dependencies.clone(),
|
||||
es_module
|
||||
.maybe_types_dependency
|
||||
.as_ref()
|
||||
.and_then(|(_, r)| r.clone()),
|
||||
),
|
||||
Module::Synthetic(synthetic_module) => match &synthetic_module
|
||||
.maybe_source
|
||||
{
|
||||
// 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 => {
|
||||
if module.kind == ModuleKind::Synthetic {
|
||||
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 {
|
||||
for (specifier, dependency) in &module.dependencies {
|
||||
if !matches!(dependency.maybe_type, Resolved::None) {
|
||||
dependencies
|
||||
.insert(specifier.clone(), dependency.maybe_type.clone());
|
||||
if let Resolved::Ok {
|
||||
specifier, range, ..
|
||||
} = &dependency.maybe_type
|
||||
{
|
||||
let entry = self.referrer_map.entry(specifier.clone());
|
||||
entry.or_insert_with(|| referrer_range.clone());
|
||||
entry.or_insert_with(|| range.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.modules.insert(
|
||||
synthetic_module.specifier.clone(),
|
||||
module.specifier.clone(),
|
||||
ModuleEntry::Configuration { dependencies },
|
||||
);
|
||||
self
|
||||
.configurations
|
||||
.insert(synthetic_module.specifier.clone());
|
||||
continue;
|
||||
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 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)]
|
||||
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 =
|
||||
graph.redirects.get(specifier).unwrap_or(specifier);
|
||||
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 {
|
||||
code,
|
||||
dependencies,
|
||||
dependencies: module.dependencies.clone(),
|
||||
media_type,
|
||||
checked_libs: Default::default(),
|
||||
maybe_types,
|
||||
|
@ -142,7 +146,7 @@ impl GraphData {
|
|||
/// Return `None` if any modules are not known.
|
||||
pub(crate) fn walk<'a>(
|
||||
&'a self,
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
follow_dynamic: bool,
|
||||
follow_type_only: bool,
|
||||
check_js: bool,
|
||||
|
@ -150,7 +154,7 @@ impl GraphData {
|
|||
let mut result = HashMap::<&'a ModuleSpecifier, &'a ModuleEntry>::new();
|
||||
let mut seen = HashSet::<&ModuleSpecifier>::new();
|
||||
let mut visiting = VecDeque::<&ModuleSpecifier>::new();
|
||||
for root in roots {
|
||||
for (root, _) in roots {
|
||||
seen.insert(root);
|
||||
visiting.push_back(root);
|
||||
}
|
||||
|
@ -181,10 +185,10 @@ impl GraphData {
|
|||
))
|
||||
&& follow_type_only;
|
||||
if check_types {
|
||||
if let Some(Ok((types, _))) = maybe_types {
|
||||
if !seen.contains(types) {
|
||||
seen.insert(types);
|
||||
visiting.push_front(types);
|
||||
if let Some(Resolved::Ok { specifier, .. }) = maybe_types {
|
||||
if !seen.contains(specifier) {
|
||||
seen.insert(specifier);
|
||||
visiting.push_front(specifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,10 +200,10 @@ impl GraphData {
|
|||
}
|
||||
#[allow(clippy::manual_flatten)]
|
||||
for resolved in resolutions {
|
||||
if let Some(Ok((dep_specifier, _))) = resolved {
|
||||
if !seen.contains(dep_specifier) {
|
||||
seen.insert(dep_specifier);
|
||||
visiting.push_front(dep_specifier);
|
||||
if let Resolved::Ok { specifier, .. } = resolved {
|
||||
if !seen.contains(specifier) {
|
||||
seen.insert(specifier);
|
||||
visiting.push_front(specifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,10 +211,12 @@ impl GraphData {
|
|||
}
|
||||
}
|
||||
ModuleEntry::Configuration { dependencies } => {
|
||||
for (dep_specifier, _) in dependencies.values().flatten() {
|
||||
if !seen.contains(dep_specifier) {
|
||||
seen.insert(dep_specifier);
|
||||
visiting.push_front(dep_specifier);
|
||||
for resolved in dependencies.values() {
|
||||
if let Resolved::Ok { specifier, .. } = resolved {
|
||||
if !seen.contains(specifier) {
|
||||
seen.insert(specifier);
|
||||
visiting.push_front(specifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +236,7 @@ impl GraphData {
|
|||
/// `roots`. Returns `None` if any roots are not known.
|
||||
pub(crate) fn graph_segment(
|
||||
&self,
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
) -> Option<Self> {
|
||||
let mut modules = HashMap::new();
|
||||
let mut referrer_map = HashMap::new();
|
||||
|
@ -257,7 +263,7 @@ impl GraphData {
|
|||
/// not known.
|
||||
pub(crate) fn check(
|
||||
&self,
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
follow_type_only: bool,
|
||||
check_js: bool,
|
||||
) -> Option<Result<(), AnyError>> {
|
||||
|
@ -283,7 +289,7 @@ impl GraphData {
|
|||
))
|
||||
&& follow_type_only;
|
||||
if check_types {
|
||||
if let Some(Err(error)) = maybe_types {
|
||||
if let Some(Resolved::Err(error)) = maybe_types {
|
||||
let range = error.range();
|
||||
if !range.specifier.as_str().contains("$deno") {
|
||||
return Some(Err(custom_error(
|
||||
|
@ -302,7 +308,7 @@ impl GraphData {
|
|||
}
|
||||
#[allow(clippy::manual_flatten)]
|
||||
for resolved in resolutions {
|
||||
if let Some(Err(error)) = resolved {
|
||||
if let Resolved::Err(error) = resolved {
|
||||
let range = error.range();
|
||||
if !range.specifier.as_str().contains("$deno") {
|
||||
return Some(Err(custom_error(
|
||||
|
@ -318,7 +324,7 @@ impl GraphData {
|
|||
}
|
||||
ModuleEntry::Configuration { dependencies } => {
|
||||
for resolved_result in dependencies.values() {
|
||||
if let Err(error) = resolved_result {
|
||||
if let Resolved::Err(error) = resolved_result {
|
||||
let range = error.range();
|
||||
if !range.specifier.as_str().contains("$deno") {
|
||||
return Some(Err(custom_error(
|
||||
|
@ -331,7 +337,7 @@ impl GraphData {
|
|||
}
|
||||
}
|
||||
ModuleEntry::Error(error) => {
|
||||
if !roots.contains(specifier) {
|
||||
if !contains_specifier(roots, specifier) {
|
||||
if let Some(range) = self.referrer_map.get(specifier) {
|
||||
if !range.specifier.as_str().contains("$deno") {
|
||||
let message = error.to_string();
|
||||
|
@ -354,7 +360,7 @@ impl GraphData {
|
|||
/// Assumes that all of those modules are known.
|
||||
pub(crate) fn set_type_checked(
|
||||
&mut self,
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
lib: &TypeLib,
|
||||
) {
|
||||
let specifiers: Vec<ModuleSpecifier> =
|
||||
|
@ -374,10 +380,10 @@ impl GraphData {
|
|||
/// Check if `roots` are all marked as type checked under `lib`.
|
||||
pub(crate) fn is_type_checked(
|
||||
&self,
|
||||
roots: &[ModuleSpecifier],
|
||||
roots: &[(ModuleSpecifier, ModuleKind)],
|
||||
lib: &TypeLib,
|
||||
) -> bool {
|
||||
roots.iter().all(|r| {
|
||||
roots.iter().all(|(r, _)| {
|
||||
let found = self.follow_redirect(r);
|
||||
match self.modules.get(&found) {
|
||||
Some(ModuleEntry::Module { checked_libs, .. }) => {
|
||||
|
|
|
@ -21,7 +21,10 @@ use std::thread;
|
|||
use tokio::sync::mpsc;
|
||||
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
|
||||
/// in its own thread.
|
||||
|
@ -105,7 +108,7 @@ impl CacheServer {
|
|||
/// client.
|
||||
pub async fn cache(
|
||||
&self,
|
||||
roots: Vec<ModuleSpecifier>,
|
||||
roots: Vec<(ModuleSpecifier, deno_graph::ModuleKind)>,
|
||||
) -> Result<(), AnyError> {
|
||||
let (tx, rx) = oneshot::channel::<Result<(), AnyError>>();
|
||||
if self.0.send((roots, tx)).is_err() {
|
||||
|
|
|
@ -20,6 +20,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::resolve_url;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Resolved;
|
||||
use deno_runtime::tokio_util::create_basic_runtime;
|
||||
use log::error;
|
||||
use lspower::lsp;
|
||||
|
@ -547,13 +548,13 @@ fn resolution_error_as_code(
|
|||
use deno_graph::SpecifierError;
|
||||
|
||||
match err {
|
||||
ResolutionError::InvalidDowngrade(_, _) => {
|
||||
ResolutionError::InvalidDowngrade { .. } => {
|
||||
lsp::NumberOrString::String("invalid-downgrade".to_string())
|
||||
}
|
||||
ResolutionError::InvalidLocalImport(_, _) => {
|
||||
ResolutionError::InvalidLocalImport { .. } => {
|
||||
lsp::NumberOrString::String("invalid-local-import".to_string())
|
||||
}
|
||||
ResolutionError::InvalidSpecifier(err, _) => match err {
|
||||
ResolutionError::InvalidSpecifier { error, .. } => match error {
|
||||
SpecifierError::ImportPrefixMissing(_, _) => {
|
||||
lsp::NumberOrString::String("import-prefix-missing".to_string())
|
||||
}
|
||||
|
@ -561,7 +562,7 @@ fn resolution_error_as_code(
|
|||
lsp::NumberOrString::String("invalid-url".to_string())
|
||||
}
|
||||
},
|
||||
ResolutionError::ResolverError(_, _, _) => {
|
||||
ResolutionError::ResolverError { .. } => {
|
||||
lsp::NumberOrString::String("resolver-error".to_string())
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +576,9 @@ fn diagnose_dependency(
|
|||
maybe_assert_type: Option<&str>,
|
||||
) {
|
||||
match resolved {
|
||||
Some(Ok((specifier, range))) => {
|
||||
Resolved::Ok {
|
||||
specifier, range, ..
|
||||
} => {
|
||||
if let Some(doc) = documents.get(specifier) {
|
||||
if let Some(message) = doc.maybe_warning() {
|
||||
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()),
|
||||
severity: Some(lsp::DiagnosticSeverity::ERROR),
|
||||
code: Some(resolution_error_as_code(err)),
|
||||
|
|
|
@ -22,7 +22,9 @@ use deno_core::error::AnyError;
|
|||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::ResolveResponse;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::Resolved;
|
||||
use lspower::lsp;
|
||||
use once_cell::sync::Lazy;
|
||||
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)]
|
||||
struct DocumentInner {
|
||||
/// contains the last-known-good set of dependencies from parsing the module
|
||||
|
@ -274,7 +224,7 @@ struct DocumentInner {
|
|||
maybe_language_id: Option<LanguageId>,
|
||||
maybe_lsp_version: Option<i32>,
|
||||
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_warning: Option<String>,
|
||||
specifier: ModuleSpecifier,
|
||||
|
@ -299,16 +249,14 @@ impl Document {
|
|||
// 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
|
||||
// parse the module.
|
||||
let maybe_module = match deno_graph::parse_module(
|
||||
let maybe_module = Some(deno_graph::parse_module(
|
||||
&specifier,
|
||||
maybe_headers,
|
||||
content.clone(),
|
||||
Some(&deno_graph::ModuleKind::Esm),
|
||||
maybe_resolver,
|
||||
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 {
|
||||
Arc::new(module.dependencies.clone())
|
||||
} else {
|
||||
|
@ -340,16 +288,14 @@ impl Document {
|
|||
let maybe_headers = language_id.as_headers();
|
||||
let parser = SourceParser::default();
|
||||
let maybe_module = if language_id.is_diagnosable() {
|
||||
match deno_graph::parse_module(
|
||||
Some(deno_graph::parse_module(
|
||||
&specifier,
|
||||
maybe_headers,
|
||||
content.clone(),
|
||||
Some(&deno_graph::ModuleKind::Esm),
|
||||
maybe_resolver,
|
||||
Some(&parser),
|
||||
) {
|
||||
Ok(m) => m.to_maybe_es_module().map(Ok),
|
||||
Err(err) => Some(Err(err)),
|
||||
}
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -411,16 +357,14 @@ impl Document {
|
|||
.map(|li| li.as_headers())
|
||||
.flatten();
|
||||
let parser = SourceParser::default();
|
||||
match deno_graph::parse_module(
|
||||
Some(deno_graph::parse_module(
|
||||
&self.0.specifier,
|
||||
maybe_headers,
|
||||
content.clone(),
|
||||
Some(&deno_graph::ModuleKind::Esm),
|
||||
maybe_resolver,
|
||||
Some(&parser),
|
||||
) {
|
||||
Ok(m) => m.to_maybe_es_module().map(Ok),
|
||||
Err(err) => Some(Err(err)),
|
||||
}
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -504,10 +448,19 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn maybe_types_dependency(&self) -> deno_graph::Resolved {
|
||||
let module_result = self.0.maybe_module.as_ref()?;
|
||||
let module = module_result.as_ref().ok()?;
|
||||
let (_, maybe_dep) = module.maybe_types_dependency.as_ref()?;
|
||||
let module_result = match self.0.maybe_module.as_ref() {
|
||||
Some(module_result) => module_result,
|
||||
_ => return deno_graph::Resolved::None,
|
||||
};
|
||||
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 {
|
||||
|
@ -525,18 +478,18 @@ impl Document {
|
|||
|
||||
fn maybe_module(
|
||||
&self,
|
||||
) -> Option<&Result<deno_graph::EsModule, deno_graph::ModuleGraphError>> {
|
||||
) -> Option<&Result<deno_graph::Module, deno_graph::ModuleGraphError>> {
|
||||
self.0.maybe_module.as_ref()
|
||||
}
|
||||
|
||||
pub fn maybe_parsed_source(
|
||||
&self,
|
||||
) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> {
|
||||
self.maybe_module().map(|r| {
|
||||
r.as_ref()
|
||||
.map(|m| m.parsed_source.clone())
|
||||
.map_err(|err| err.clone())
|
||||
})
|
||||
let module_result = self.maybe_module()?;
|
||||
match module_result {
|
||||
Ok(module) => Some(Ok(module.maybe_parsed_source.clone()?)),
|
||||
Err(err) => Some(Err(err.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> {
|
||||
|
@ -576,14 +529,9 @@ impl Document {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_hover_text(
|
||||
result: &Result<
|
||||
(ModuleSpecifier, deno_graph::Range),
|
||||
deno_graph::ResolutionError,
|
||||
>,
|
||||
) -> String {
|
||||
pub(crate) fn to_hover_text(result: &Resolved) -> String {
|
||||
match result {
|
||||
Ok((specifier, _)) => match specifier.scheme() {
|
||||
Resolved::Ok { specifier, .. } => match specifier.scheme() {
|
||||
"data" => "_(a data url)_".to_string(),
|
||||
"blob" => "_(a blob url)_".to_string(),
|
||||
_ => format!(
|
||||
|
@ -593,7 +541,8 @@ pub(crate) fn to_hover_text(
|
|||
)
|
||||
.replace('@', "​@"),
|
||||
},
|
||||
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>>,
|
||||
/// Any imports to the context supplied by configuration files. This is like
|
||||
/// 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.
|
||||
maybe_import_map: Option<ImportMapResolver>,
|
||||
/// The optional JSX resolver, which is used when JSX imports are configured.
|
||||
|
@ -913,7 +862,7 @@ impl Documents {
|
|||
) -> bool {
|
||||
let maybe_resolver = self.get_maybe_resolver();
|
||||
let maybe_specifier = if let Some(resolver) = maybe_resolver {
|
||||
resolver.resolve(specifier, referrer).ok()
|
||||
resolver.resolve(specifier, referrer).to_result().ok()
|
||||
} else {
|
||||
deno_core::resolve_import(specifier, referrer.as_str()).ok()
|
||||
};
|
||||
|
@ -1043,14 +992,14 @@ impl Documents {
|
|||
results.push(None);
|
||||
}
|
||||
} 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));
|
||||
} else if let Some(Ok((specifier, _))) = &dep.maybe_code {
|
||||
} else if let Resolved::Ok { specifier, .. } = &dep.maybe_code {
|
||||
results.push(self.resolve_dependency(specifier));
|
||||
} else {
|
||||
results.push(None);
|
||||
}
|
||||
} else if let Some(Some(Ok((specifier, _)))) =
|
||||
} else if let Some(Resolved::Ok { specifier, .. }) =
|
||||
self.resolve_imports_dependency(&specifier)
|
||||
{
|
||||
// clone here to avoid double borrow of self
|
||||
|
@ -1121,9 +1070,7 @@ impl Documents {
|
|||
imports
|
||||
.into_iter()
|
||||
.map(|(referrer, dependencies)| {
|
||||
let dependencies =
|
||||
dependencies.into_iter().map(|s| (s, None)).collect();
|
||||
let module = SyntheticModule::new(
|
||||
let module = Module::new_from_type_imports(
|
||||
referrer.clone(),
|
||||
dependencies,
|
||||
self.get_maybe_resolver(),
|
||||
|
@ -1167,7 +1114,9 @@ impl Documents {
|
|||
.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
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
|
@ -1198,12 +1147,10 @@ impl Documents {
|
|||
.map(|m| {
|
||||
m.maybe_types_dependency
|
||||
.as_ref()
|
||||
.map(|(_, o)| o.as_ref().map(|r| r.as_ref().ok()).flatten())
|
||||
.flatten()
|
||||
.map(|(_, resolved)| resolved.clone())
|
||||
})
|
||||
.flatten()
|
||||
.cloned();
|
||||
if let Some((specifier, _)) = maybe_types_dependency {
|
||||
.flatten();
|
||||
if let Some(Resolved::Ok { specifier, .. }) = maybe_types_dependency {
|
||||
self.resolve_dependency(&specifier)
|
||||
} else {
|
||||
let media_type = doc.media_type();
|
||||
|
@ -1221,7 +1168,7 @@ impl Documents {
|
|||
for module in self.imports.values() {
|
||||
let maybe_dep = module.dependencies.get(specifier);
|
||||
if maybe_dep.is_some() {
|
||||
return maybe_dep;
|
||||
return maybe_dep.map(|d| &d.maybe_type);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
@ -8,6 +8,7 @@ use deno_core::serde_json;
|
|||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Resolved;
|
||||
use import_map::ImportMap;
|
||||
use log::error;
|
||||
use log::info;
|
||||
|
@ -1058,34 +1059,38 @@ impl Inner {
|
|||
.get_code()
|
||||
.map(|s| self.documents.get(s))
|
||||
.flatten()
|
||||
.map(|d| d.maybe_types_dependency())
|
||||
.flatten();
|
||||
let value = match (&dep.maybe_code, &dep.maybe_type, &dep_maybe_types_dependency) {
|
||||
(Some(code_dep), Some(type_dep), None) => format!(
|
||||
.map(|d| d.maybe_types_dependency());
|
||||
let value = match (dep.maybe_code.is_none(), dep.maybe_type.is_none(), &dep_maybe_types_dependency) {
|
||||
(false, false, None) => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
|
||||
to_hover_text(code_dep),
|
||||
to_hover_text(type_dep)
|
||||
to_hover_text(&dep.maybe_code),
|
||||
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",
|
||||
to_hover_text(code_dep),
|
||||
to_hover_text(types_dep),
|
||||
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(&dep.maybe_code),
|
||||
to_hover_text(&dep.maybe_type),
|
||||
to_hover_text(types_dep)
|
||||
),
|
||||
(None, Some(type_dep), _) => format!(
|
||||
"**Resolved Dependency**\n\n**Types**: {}\n",
|
||||
to_hover_text(type_dep)
|
||||
(false, false, Some(_)) => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
|
||||
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 =
|
||||
if let Some(docs) = self.module_registries.get_hover(&dep).await {
|
||||
|
@ -2677,10 +2682,15 @@ impl Inner {
|
|||
params
|
||||
.uris
|
||||
.iter()
|
||||
.map(|t| self.url_map.normalize_url(&t.uri))
|
||||
.map(|t| {
|
||||
(
|
||||
self.url_map.normalize_url(&t.uri),
|
||||
deno_graph::ModuleKind::Esm,
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
vec![referrer.clone()]
|
||||
vec![(referrer.clone(), deno_graph::ModuleKind::Esm)]
|
||||
};
|
||||
|
||||
if self.maybe_cache_server.is_none() {
|
||||
|
|
18
cli/main.rs
18
cli/main.rs
|
@ -397,7 +397,9 @@ async fn compile_command(
|
|||
.then(|| {
|
||||
let root_module = graph.as_ref().modules()[0];
|
||||
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,
|
||||
}
|
||||
})
|
||||
|
@ -467,7 +469,7 @@ async fn info_command(
|
|||
.map(|im| im.as_resolver())
|
||||
};
|
||||
let graph = deno_graph::create_graph(
|
||||
vec![specifier],
|
||||
vec![(specifier, deno_graph::ModuleKind::Esm)],
|
||||
false,
|
||||
None,
|
||||
&mut cache,
|
||||
|
@ -547,7 +549,7 @@ async fn cache_command(
|
|||
for file in cache_flags.files {
|
||||
let specifier = resolve_url_or_path(&file)?;
|
||||
ps.prepare_module_load(
|
||||
vec![specifier],
|
||||
vec![(specifier, deno_graph::ModuleKind::Esm)],
|
||||
false,
|
||||
lib.clone(),
|
||||
Permissions::allow_all(),
|
||||
|
@ -639,7 +641,7 @@ async fn create_graph_and_maybe_check(
|
|||
};
|
||||
let graph = Arc::new(
|
||||
deno_graph::create_graph(
|
||||
vec![root],
|
||||
vec![(root, deno_graph::ModuleKind::Esm)],
|
||||
false,
|
||||
maybe_imports,
|
||||
&mut cache,
|
||||
|
@ -707,7 +709,7 @@ fn bundle_module_graph(
|
|||
ps: &ProcState,
|
||||
flags: &Flags,
|
||||
) -> 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(
|
||||
emit::ConfigType::Bundle,
|
||||
|
@ -777,7 +779,7 @@ async fn bundle_command(
|
|||
.filter_map(|(_, r)| {
|
||||
r.as_ref()
|
||||
.ok()
|
||||
.map(|(s, _)| s.to_file_path().ok())
|
||||
.map(|(s, _, _)| s.to_file_path().ok())
|
||||
.flatten()
|
||||
})
|
||||
.collect();
|
||||
|
@ -992,7 +994,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
|||
.map(|im| im.as_resolver())
|
||||
};
|
||||
let graph = deno_graph::create_graph(
|
||||
vec![main_module.clone()],
|
||||
vec![(main_module.clone(), deno_graph::ModuleKind::Esm)],
|
||||
false,
|
||||
maybe_imports,
|
||||
&mut cache,
|
||||
|
@ -1016,7 +1018,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<i32, AnyError> {
|
|||
.filter_map(|(_, r)| {
|
||||
r.as_ref()
|
||||
.ok()
|
||||
.map(|(s, _)| s.to_file_path().ok())
|
||||
.map(|(s, _, _)| s.to_file_path().ok())
|
||||
.flatten()
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -108,7 +108,7 @@ impl ModuleLoader for CliModuleLoader {
|
|||
|
||||
async move {
|
||||
ps.prepare_module_load(
|
||||
vec![specifier],
|
||||
vec![(specifier, deno_graph::ModuleKind::Esm)],
|
||||
is_dynamic,
|
||||
lib,
|
||||
root_permissions,
|
||||
|
|
|
@ -24,6 +24,7 @@ use deno_core::serde_json::Value;
|
|||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
@ -207,9 +208,9 @@ async fn op_emit(
|
|||
.as_ref()
|
||||
.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 =
|
||||
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(
|
||||
deno_graph::create_graph(
|
||||
roots,
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::resolver::JsxResolver;
|
|||
use crate::source_maps::SourceMapGetter;
|
||||
use crate::version;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::custom_error;
|
||||
|
@ -41,7 +42,8 @@ use deno_graph::create_graph;
|
|||
use deno_graph::source::CacheInfo;
|
||||
use deno_graph::source::LoadFuture;
|
||||
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_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
|
@ -252,7 +254,7 @@ impl ProcState {
|
|||
/// emits where necessary or report any module graph / type checking errors.
|
||||
pub(crate) async fn prepare_module_load(
|
||||
&self,
|
||||
roots: Vec<ModuleSpecifier>,
|
||||
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
||||
is_dynamic: bool,
|
||||
lib: emit::TypeLib,
|
||||
root_permissions: Permissions,
|
||||
|
@ -262,7 +264,7 @@ impl ProcState {
|
|||
// TODO(bartlomieju): this is very make-shift, is there an existing API
|
||||
// that we could include it like with "maybe_imports"?
|
||||
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
|
||||
} else {
|
||||
|
@ -438,21 +440,21 @@ impl ProcState {
|
|||
let graph_data = self.graph_data.read();
|
||||
let found_referrer = graph_data.follow_redirect(&referrer);
|
||||
let maybe_resolved = match graph_data.get(&found_referrer) {
|
||||
Some(ModuleEntry::Module { dependencies, .. }) => dependencies
|
||||
.get(specifier)
|
||||
.and_then(|dep| dep.maybe_code.clone()),
|
||||
Some(ModuleEntry::Module { dependencies, .. }) => {
|
||||
dependencies.get(specifier).map(|d| &d.maybe_code)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match maybe_resolved {
|
||||
Some(Ok((specifier, _))) => return Ok(specifier),
|
||||
Some(Err(err)) => {
|
||||
Some(Resolved::Ok { specifier, .. }) => return Ok(specifier.clone()),
|
||||
Some(Resolved::Err(err)) => {
|
||||
return Err(custom_error(
|
||||
"TypeError",
|
||||
format!("{}\n", err.to_string_with_range()),
|
||||
))
|
||||
}
|
||||
None => {}
|
||||
Some(Resolved::None) | None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +474,7 @@ impl ProcState {
|
|||
None
|
||||
};
|
||||
if let Some(resolver) = &maybe_resolver {
|
||||
resolver.resolve(specifier, &referrer)
|
||||
resolver.resolve(specifier, &referrer).to_result()
|
||||
} else {
|
||||
deno_core::resolve_import(specifier, referrer.as_str())
|
||||
.map_err(|err| err.into())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_import;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::ResolveResponse;
|
||||
use deno_graph::source::Resolver;
|
||||
use import_map::ImportMap;
|
||||
use std::sync::Arc;
|
||||
|
@ -28,11 +28,11 @@ impl Resolver for ImportMapResolver {
|
|||
&self,
|
||||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
self
|
||||
.0
|
||||
.resolve(specifier, referrer)
|
||||
.map_err(|err| err.into())
|
||||
) -> ResolveResponse {
|
||||
match self.0.resolve(specifier, referrer) {
|
||||
Ok(specifier) => ResolveResponse::Specifier(specifier),
|
||||
Err(err) => ResolveResponse::Err(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,9 +67,12 @@ impl Resolver for JsxResolver {
|
|||
&self,
|
||||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> ResolveResponse {
|
||||
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),
|
||||
)
|
||||
}
|
||||
|
|
9
cli/tests/testdata/055_info_file_json.out
vendored
9
cli/tests/testdata/055_info_file_json.out
vendored
|
@ -22,10 +22,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]005_more_imports.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/005_more_imports.ts"
|
||||
},
|
||||
{
|
||||
|
@ -47,18 +47,17 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]mod1.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/subdir/mod1.ts"
|
||||
},
|
||||
{
|
||||
"dependencies": [],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]print_hello.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/subdir/print_hello.ts"
|
||||
},
|
||||
{
|
||||
|
@ -80,10 +79,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]mod2.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts"
|
||||
}
|
||||
],
|
||||
|
|
11
cli/tests/testdata/076_info_json_deps_order.out
vendored
11
cli/tests/testdata/076_info_json_deps_order.out
vendored
|
@ -22,10 +22,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]076_info_json_deps_order.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/076_info_json_deps_order.ts"
|
||||
},
|
||||
{
|
||||
|
@ -63,10 +63,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]A.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/recursive_imports/A.ts"
|
||||
},
|
||||
{
|
||||
|
@ -104,10 +104,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]B.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/recursive_imports/B.ts"
|
||||
},
|
||||
{
|
||||
|
@ -145,18 +145,17 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]C.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/recursive_imports/C.ts"
|
||||
},
|
||||
{
|
||||
"dependencies": [],
|
||||
"kind": "esm",
|
||||
"local": "[WILDCARD]common.ts",
|
||||
[WILDCARD]
|
||||
"mediaType": "TypeScript",
|
||||
[WILDCARD]
|
||||
"specifier": "file://[WILDCARD]/recursive_imports/common.ts"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -18,7 +18,9 @@ use deno_graph::create_graph;
|
|||
use deno_graph::source::LoadFuture;
|
||||
use deno_graph::source::LoadResponse;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_graph::source::ResolveResponse;
|
||||
use deno_graph::source::Resolver;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_graph::ModuleSpecifier;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use import_map::ImportMap;
|
||||
|
@ -47,17 +49,18 @@ impl Resolver for DocResolver {
|
|||
&self,
|
||||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> ResolveResponse {
|
||||
if let Some(import_map) = &self.import_map {
|
||||
return import_map
|
||||
.resolve(specifier, referrer)
|
||||
.map_err(AnyError::from);
|
||||
return match import_map.resolve(specifier, referrer) {
|
||||
Ok(specifier) => ResolveResponse::Specifier(specifier),
|
||||
Err(err) => ResolveResponse::Err(err.into()),
|
||||
};
|
||||
}
|
||||
|
||||
let module_specifier =
|
||||
deno_core::resolve_import(specifier, referrer.as_str())?;
|
||||
|
||||
Ok(module_specifier)
|
||||
match deno_core::resolve_import(specifier, referrer.as_str()) {
|
||||
Ok(specifier) => ResolveResponse::Specifier(specifier),
|
||||
Err(err) => ResolveResponse::Err(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +107,7 @@ pub async fn print_docs(
|
|||
let source_file_specifier =
|
||||
ModuleSpecifier::parse("deno://lib.deno.d.ts").unwrap();
|
||||
let graph = create_graph(
|
||||
vec![source_file_specifier.clone()],
|
||||
vec![(source_file_specifier.clone(), ModuleKind::Esm)],
|
||||
false,
|
||||
None,
|
||||
&mut loader,
|
||||
|
@ -144,7 +147,7 @@ pub async fn print_docs(
|
|||
import_map: ps.maybe_import_map.clone(),
|
||||
};
|
||||
let graph = create_graph(
|
||||
vec![root_specifier.clone()],
|
||||
vec![(root_specifier.clone(), ModuleKind::Esm)],
|
||||
false,
|
||||
None,
|
||||
&mut loader,
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::flags::TestFlags;
|
|||
use crate::fs_util::collect_specifiers;
|
||||
use crate::fs_util::is_supported_test_ext;
|
||||
use crate::fs_util::is_supported_test_path;
|
||||
use crate::graph_util::contains_specifier;
|
||||
use crate::graph_util::graph_valid;
|
||||
use crate::located_script_name;
|
||||
use crate::lockfile;
|
||||
|
@ -34,7 +35,7 @@ use deno_core::futures::FutureExt;
|
|||
use deno_core::futures::StreamExt;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use deno_runtime::tokio_util::run_basic;
|
||||
use log::Level;
|
||||
|
@ -724,7 +725,7 @@ async fn check_specifiers(
|
|||
if !inline_files.is_empty() {
|
||||
let specifiers = inline_files
|
||||
.iter()
|
||||
.map(|file| file.specifier.clone())
|
||||
.map(|file| (file.specifier.clone(), ModuleKind::Esm))
|
||||
.collect();
|
||||
|
||||
for file in inline_files {
|
||||
|
@ -746,7 +747,7 @@ async fn check_specifiers(
|
|||
.iter()
|
||||
.filter_map(|(specifier, mode)| {
|
||||
if *mode != TestMode::Documentation {
|
||||
Some(specifier.clone())
|
||||
Some((specifier.clone(), ModuleKind::Esm))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1113,7 +1114,7 @@ pub async fn run_tests_with_watch(
|
|||
} else {
|
||||
test_modules
|
||||
.iter()
|
||||
.filter_map(|url| deno_core::resolve_url(url.as_str()).ok())
|
||||
.map(|url| (url.clone(), ModuleKind::Esm))
|
||||
.collect()
|
||||
};
|
||||
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())
|
||||
};
|
||||
let graph = deno_graph::create_graph(
|
||||
test_modules.clone(),
|
||||
test_modules
|
||||
.iter()
|
||||
.map(|s| (s.clone(), ModuleKind::Esm))
|
||||
.collect(),
|
||||
false,
|
||||
maybe_imports,
|
||||
cache.as_mut_loader(),
|
||||
|
@ -1151,7 +1155,7 @@ pub async fn run_tests_with_watch(
|
|||
output: &mut HashSet<&'a ModuleSpecifier>,
|
||||
no_check: bool,
|
||||
) {
|
||||
if let Some(Module::Es(module)) = maybe_module {
|
||||
if let Some(module) = maybe_module {
|
||||
for dep in module.dependencies.values() {
|
||||
if let Some(specifier) = &dep.get_code() {
|
||||
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()
|
||||
}) {
|
||||
if modules.contains(&&path) {
|
||||
modules_to_reload.push(specifier);
|
||||
modules_to_reload.push((specifier, ModuleKind::Esm));
|
||||
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 include = include.clone();
|
||||
let ignore = ignore.clone();
|
||||
|
@ -1245,7 +1249,9 @@ pub async fn run_tests_with_watch(
|
|||
)
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|(specifier, _)| modules_to_reload.contains(specifier))
|
||||
.filter(|(specifier, _)| {
|
||||
contains_specifier(&modules_to_reload, specifier)
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<(ModuleSpecifier, TestMode)>>();
|
||||
|
||||
|
|
20
cli/tsc.rs
20
cli/tsc.rs
|
@ -25,6 +25,7 @@ use deno_core::ModuleSpecifier;
|
|||
use deno_core::OpFn;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_core::Snapshot;
|
||||
use deno_graph::Resolved;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
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 resolved_dep = match graph_data.get(&referrer) {
|
||||
Some(ModuleEntry::Module { dependencies, .. }) => {
|
||||
dependencies.get(specifier).and_then(|d| {
|
||||
d.maybe_type.as_ref().or_else(|| d.maybe_code.as_ref())
|
||||
dependencies.get(specifier).map(|d| {
|
||||
if matches!(d.maybe_type, Resolved::Ok { .. }) {
|
||||
&d.maybe_type
|
||||
} else {
|
||||
&d.maybe_code
|
||||
}
|
||||
})
|
||||
}
|
||||
Some(ModuleEntry::Configuration { dependencies }) => {
|
||||
|
@ -523,7 +528,7 @@ fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
|
|||
_ => None,
|
||||
};
|
||||
let maybe_result = match resolved_dep {
|
||||
Some(Ok((specifier, _))) => {
|
||||
Some(Resolved::Ok { specifier, .. }) => {
|
||||
let specifier = graph_data.follow_redirect(specifier);
|
||||
match graph_data.get(&specifier) {
|
||||
Some(ModuleEntry::Module {
|
||||
|
@ -531,8 +536,8 @@ fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
|
|||
maybe_types,
|
||||
..
|
||||
}) => match maybe_types {
|
||||
Some(Ok((types, _))) => {
|
||||
let types = graph_data.follow_redirect(types);
|
||||
Some(Resolved::Ok { specifier, .. }) => {
|
||||
let types = graph_data.follow_redirect(specifier);
|
||||
match graph_data.get(&types) {
|
||||
Some(ModuleEntry::Module { media_type, .. }) => {
|
||||
Some((types, media_type))
|
||||
|
@ -698,6 +703,7 @@ mod tests {
|
|||
use crate::diagnostics::DiagnosticCategory;
|
||||
use crate::emit::Stats;
|
||||
use deno_core::futures::future;
|
||||
use deno_graph::ModuleKind;
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -741,7 +747,7 @@ mod tests {
|
|||
let fixtures = test_util::testdata_path().join("tsc2");
|
||||
let mut loader = MockLoader { fixtures };
|
||||
let graph = deno_graph::create_graph(
|
||||
vec![specifier],
|
||||
vec![(specifier, ModuleKind::Esm)],
|
||||
false,
|
||||
None,
|
||||
&mut loader,
|
||||
|
@ -768,7 +774,7 @@ mod tests {
|
|||
let fixtures = test_util::testdata_path().join("tsc2");
|
||||
let mut loader = MockLoader { fixtures };
|
||||
let graph = deno_graph::create_graph(
|
||||
vec![specifier.clone()],
|
||||
vec![(specifier.clone(), ModuleKind::Esm)],
|
||||
false,
|
||||
None,
|
||||
&mut loader,
|
||||
|
|
Loading…
Reference in a new issue