diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-01-10 17:40:30 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-10 22:40:30 +0000 |
commit | 70ac06138c18cf643e7e1947dee54f3adff13de3 (patch) | |
tree | 73cd8fb7fe51ecbdcf47770b15b27f6fb49b4d05 /cli/tsc/diagnostics.rs | |
parent | 515a34b4de222e35c7ade1b92614d746e73d4c2e (diff) |
feat(unstable): fast subset type checking of JSR dependencies (#21873)
Diffstat (limited to 'cli/tsc/diagnostics.rs')
-rw-r--r-- | cli/tsc/diagnostics.rs | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/cli/tsc/diagnostics.rs b/cli/tsc/diagnostics.rs index b11a8b536..56610106b 100644 --- a/cli/tsc/diagnostics.rs +++ b/cli/tsc/diagnostics.rs @@ -1,11 +1,14 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use deno_ast::ModuleSpecifier; +use deno_graph::ModuleGraph; use deno_runtime::colors; use deno_core::serde::Deserialize; use deno_core::serde::Deserializer; use deno_core::serde::Serialize; use deno_core::serde::Serializer; +use deno_core::sourcemap::SourceMap; use std::error::Error; use std::fmt; @@ -101,7 +104,9 @@ impl DiagnosticMessageChain { #[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Position { + /// 0-indexed line number pub line: u64, + /// 0-indexed character number pub character: u64, } @@ -112,6 +117,13 @@ pub struct Diagnostic { pub code: u64, pub start: Option<Position>, pub end: Option<Position>, + /// Position of this diagnostic in the original non-mapped source. + /// + /// This will exist and be different from the `start` for fast + /// checked modules where the TypeScript source will differ + /// from the original source. + #[serde(skip_serializing)] + pub original_source_start: Option<Position>, pub message_text: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub message_chain: Option<DiagnosticMessageChain>, @@ -145,9 +157,10 @@ impl Diagnostic { } fn fmt_frame(&self, f: &mut fmt::Formatter, level: usize) -> fmt::Result { - if let (Some(file_name), Some(start)) = - (self.file_name.as_ref(), self.start.as_ref()) - { + if let (Some(file_name), Some(start)) = ( + self.file_name.as_ref(), + self.original_source_start.as_ref().or(self.start.as_ref()), + ) { write!( f, "\n{:indent$} at {}:{}:{}", @@ -273,6 +286,51 @@ impl Diagnostics { pub fn is_empty(&self) -> bool { self.0.is_empty() } + + /// Modifies all the diagnostics to have their display positions + /// modified to point at the original source. + pub fn apply_fast_check_source_maps(&mut self, graph: &ModuleGraph) { + fn visit_diagnostic(d: &mut Diagnostic, graph: &ModuleGraph) { + if let Some(specifier) = d + .file_name + .as_ref() + .and_then(|n| ModuleSpecifier::parse(n).ok()) + { + if let Ok(Some(module)) = graph.try_get_prefer_types(&specifier) { + if let Some(fast_check_module) = + module.esm().and_then(|m| m.fast_check_module()) + { + // todo(dsherret): use a short lived cache to prevent parsing + // source maps so often + if let Ok(source_map) = + SourceMap::from_slice(&fast_check_module.source_map) + { + if let Some(start) = d.start.as_mut() { + let maybe_token = source_map + .lookup_token(start.line as u32, start.character as u32); + if let Some(token) = maybe_token { + d.original_source_start = Some(Position { + line: token.get_src_line() as u64, + character: token.get_src_col() as u64, + }); + } + } + } + } + } + } + + if let Some(related) = &mut d.related_information { + for d in related.iter_mut() { + visit_diagnostic(d, graph); + } + } + } + + for d in &mut self.0 { + visit_diagnostic(d, graph); + } + } } impl<'de> Deserialize<'de> for Diagnostics { |