1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 16:19:12 -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]]
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",

View file

@ -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"

View file

@ -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(), &current_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]

View file

@ -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
.get(CacheType::Version, &module.specifier)
.map_or(false, |v| {
v == get_version(module.source.as_bytes(), &config_bytes)
});
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.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));
}
}

View file

@ -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",
}

View file

@ -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)

View file

@ -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 => {
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());
}
}
if module.kind == ModuleKind::Synthetic {
let mut dependencies = BTreeMap::new();
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(|| 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 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, .. }) => {

View file

@ -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() {

View file

@ -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)),

View file

@ -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()?;
maybe_dep.clone()
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('@', "&#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>>,
/// 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

View file

@ -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() {

View file

@ -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();

View file

@ -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,

View file

@ -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,

View file

@ -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())

View file

@ -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),
)
}

View file

@ -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"
}
],

View file

@ -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"
}
],

View file

@ -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,

View file

@ -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)>>();

View file

@ -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,