summaryrefslogtreecommitdiff
path: root/cli/tsc
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-01-10 17:40:30 -0500
committerGitHub <noreply@github.com>2024-01-10 22:40:30 +0000
commit70ac06138c18cf643e7e1947dee54f3adff13de3 (patch)
tree73cd8fb7fe51ecbdcf47770b15b27f6fb49b4d05 /cli/tsc
parent515a34b4de222e35c7ade1b92614d746e73d4c2e (diff)
feat(unstable): fast subset type checking of JSR dependencies (#21873)
Diffstat (limited to 'cli/tsc')
-rw-r--r--cli/tsc/diagnostics.rs64
-rw-r--r--cli/tsc/mod.rs9
2 files changed, 68 insertions, 5 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 {
diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs
index 4e9b6110b..4df841cd3 100644
--- a/cli/tsc/mod.rs
+++ b/cli/tsc/mod.rs
@@ -486,7 +486,11 @@ fn op_load(
match module {
Module::Esm(module) => {
media_type = module.media_type;
- Some(Cow::Borrowed(&*module.source))
+ let source = module
+ .fast_check_module()
+ .map(|m| &*m.source)
+ .unwrap_or(&*module.source);
+ Some(Cow::Borrowed(source))
}
Module::Json(module) => {
media_type = MediaType::Json;
@@ -586,7 +590,7 @@ fn op_resolve(
let resolved_dep = graph
.get(&referrer)
.and_then(|m| m.esm())
- .and_then(|m| m.dependencies.get(&specifier))
+ .and_then(|m| m.dependencies_prefer_fast_check().get(&specifier))
.and_then(|d| d.maybe_type.ok().or_else(|| d.maybe_code.ok()));
let maybe_result = match resolved_dep {
@@ -1182,6 +1186,7 @@ mod tests {
code: 5023,
start: None,
end: None,
+ original_source_start: None,
message_text: Some(
"Unknown compiler option \'invalid\'.".to_string()
),