diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2021-04-20 22:22:22 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-20 22:22:22 +1000 |
commit | 115197ffb06aad2a3045e8478980ab911b5a5eeb (patch) | |
tree | 551e06136900d005155e8c0869dec23afcf51d4a /cli/lsp/sources.rs | |
parent | 8424647d22fd0c18ddefc5969250afc20fcc7a3b (diff) |
fix(#10031): lsp handles x-typescript-types header on type only imports properly (#10261)
Diffstat (limited to 'cli/lsp/sources.rs')
-rw-r--r-- | cli/lsp/sources.rs | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/cli/lsp/sources.rs b/cli/lsp/sources.rs index 072e49470..aa72ab904 100644 --- a/cli/lsp/sources.rs +++ b/cli/lsp/sources.rs @@ -315,7 +315,7 @@ impl Inner { &media_type, &self.maybe_import_map, ); - if metadata.maybe_types.is_none() { + if maybe_types.is_some() { metadata.maybe_types = maybe_types; } self.metadata.insert(specifier.clone(), metadata.clone()); @@ -383,7 +383,22 @@ impl Inner { if let analysis::ResolvedDependency::Resolved(resolved_specifier) = type_dependency { - self.resolution_result(resolved_specifier) + // even if we have a module in the maybe_types slot, it doesn't mean + // that it is the actual module we should be using based on headers, + // so we check here and update properly. + if let Some(type_dependency) = self.get_maybe_types(resolved_specifier) + { + self.set_maybe_type(specifier, &referrer, &type_dependency); + if let analysis::ResolvedDependency::Resolved(type_specifier) = + type_dependency + { + self.resolution_result(&type_specifier) + } else { + self.resolution_result(resolved_specifier) + } + } else { + self.resolution_result(resolved_specifier) + } } else { None } @@ -499,6 +514,39 @@ mod tests { } #[test] + /// This is a regression test for https://github.com/denoland/deno/issues/10031 + fn test_resolve_dependency_import_types() { + let (sources, location) = setup(); + let cache = HttpCache::new(&location); + let specifier_dep = resolve_url("https://deno.land/x/mod.ts").unwrap(); + cache + .set( + &specifier_dep, + Default::default(), + b"import type { A } from \"https://deno.land/x/lib.js\";\nconst a: A = { a: \"a\" };", + ) + .unwrap(); + let specifier_code = resolve_url("https://deno.land/x/lib.js").unwrap(); + let mut headers_code = HashMap::new(); + headers_code + .insert("x-typescript-types".to_string(), "./lib.d.ts".to_string()); + cache + .set(&specifier_code, headers_code, b"export const a = 1;") + .unwrap(); + let specifier_type = resolve_url("https://deno.land/x/lib.d.ts").unwrap(); + cache + .set( + &specifier_type, + Default::default(), + b"export const a: number;\nexport interface A { a: number; }\n", + ) + .unwrap(); + let actual = + sources.resolve_import("https://deno.land/x/lib.js", &specifier_dep); + assert_eq!(actual, Some((specifier_type, MediaType::Dts))) + } + + #[test] fn test_resolve_dependency_evil_redirect() { let (sources, location) = setup(); let cache = HttpCache::new(&location); |