diff options
Diffstat (limited to 'cli/tools/registry/graph.rs')
-rw-r--r-- | cli/tools/registry/graph.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/cli/tools/registry/graph.rs b/cli/tools/registry/graph.rs index 4d061e3da..2a3b4cc17 100644 --- a/cli/tools/registry/graph.rs +++ b/cli/tools/registry/graph.rs @@ -10,7 +10,11 @@ use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_graph::FastCheckDiagnostic; +use deno_graph::ModuleEntryRef; use deno_graph::ModuleGraph; +use deno_graph::ResolutionResolved; +use deno_graph::WalkOptions; +use lsp_types::Url; use super::diagnostics::PublishDiagnostic; use super::diagnostics::PublishDiagnosticsCollector; @@ -64,6 +68,75 @@ pub fn resolve_config_file_roots_from_exports( Ok(exports) } +pub fn collect_invalid_external_imports( + graph: &ModuleGraph, + diagnostics_collector: &PublishDiagnosticsCollector, +) { + let mut visited = HashSet::new(); + let mut skip_specifiers: HashSet<Url> = HashSet::new(); + + let mut collect_if_invalid = + |skip_specifiers: &mut HashSet<Url>, resolution: &ResolutionResolved| { + if visited.insert(resolution.specifier.clone()) { + match resolution.specifier.scheme() { + "file" | "data" => {} + "jsr" | "npm" => { + skip_specifiers.insert(resolution.specifier.clone()); + } + "http" | "https" => { + skip_specifiers.insert(resolution.specifier.clone()); + diagnostics_collector.push( + PublishDiagnostic::InvalidExternalImport { + kind: format!("non-JSR '{}'", resolution.specifier.scheme()), + imported: resolution.specifier.clone(), + referrer: resolution.range.clone(), + }, + ); + } + _ => { + skip_specifiers.insert(resolution.specifier.clone()); + diagnostics_collector.push( + PublishDiagnostic::InvalidExternalImport { + kind: format!("'{}'", resolution.specifier.scheme()), + imported: resolution.specifier.clone(), + referrer: resolution.range.clone(), + }, + ); + } + } + } + }; + + let options = WalkOptions { + check_js: true, + follow_dynamic: true, + follow_type_only: true, + }; + let mut iter = graph.walk(&graph.roots, options); + while let Some((specifier, entry)) = iter.next() { + if skip_specifiers.contains(specifier) { + iter.skip_previous_dependencies(); + continue; + } + + let ModuleEntryRef::Module(module) = entry else { + continue; + }; + let Some(module) = module.esm() else { + continue; + }; + + for (_, dep) in &module.dependencies { + if let Some(resolved) = dep.maybe_code.ok() { + collect_if_invalid(&mut skip_specifiers, resolved); + } + if let Some(resolved) = dep.maybe_type.ok() { + collect_if_invalid(&mut skip_specifiers, resolved); + } + } + } +} + /// Collects diagnostics from the module graph for the given packages. /// Returns true if any diagnostics were collected. pub fn collect_fast_check_type_graph_diagnostics( |