1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-21 23:04:45 -05:00

fix(lsp): properly resolve jsxImportSource for caching (#25688)

This commit is contained in:
Nayeem Rahman 2024-09-17 18:29:19 +01:00 committed by GitHub
parent d4a06251c5
commit f360cae9dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 20 deletions

View file

@ -1,6 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use base64::Engine;
use deno_ast::MediaType;
use deno_config::workspace::WorkspaceDirectory;
use deno_config::workspace::WorkspaceDiscoverOptions;
@ -968,16 +967,27 @@ impl Inner {
(|| {
let compiler_options = config_file.to_compiler_options().ok()?.options;
let jsx_import_source = compiler_options.get("jsxImportSource")?;
let jsx_import_source = jsx_import_source.as_str()?;
let jsx_import_source = jsx_import_source.as_str()?.to_string();
let referrer = config_file.specifier.clone();
let specifier = Url::parse(&format!(
"data:application/typescript;base64,{}",
base64::engine::general_purpose::STANDARD
.encode(format!("import '{jsx_import_source}/jsx-runtime';"))
))
.unwrap();
let specifier = format!("{jsx_import_source}/jsx-runtime");
self.task_queue.queue_task(Box::new(|ls: LanguageServer| {
spawn(async move {
let specifier = {
let inner = ls.inner.read().await;
let resolver = inner.resolver.as_graph_resolver(Some(&referrer));
let Ok(specifier) = resolver.resolve(
&specifier,
&deno_graph::Range {
specifier: referrer.clone(),
start: deno_graph::Position::zeroed(),
end: deno_graph::Position::zeroed(),
},
deno_graph::source::ResolutionMode::Types,
) else {
return;
};
specifier
};
if let Err(err) = ls.cache(vec![specifier], referrer, false).await {
lsp_warn!("{:#}", err);
}

View file

@ -11659,27 +11659,111 @@ fn lsp_jsx_import_source_config_file_automatic_cache() {
// The caching is done on an asynchronous task spawned after init, so there's
// a chance it wasn't done in time and we need to wait for another batch of
// diagnostics.
let mut version = 1;
while !diagnostics.all().is_empty() {
std::thread::sleep(std::time::Duration::from_millis(50));
// The post-cache diagnostics update triggers inconsistently on CI for some
// reason. Force it with this notification.
diagnostics = client.did_open(json!({
"textDocument": {
"uri": temp_dir.url().join("file.tsx").unwrap(),
"languageId": "typescriptreact",
"version": 1,
"text": "
export function Foo() {
return <div></div>;
}
",
},
}));
version += 1;
client.write_notification(
"textDocument/didChange",
json!({
"textDocument": {
"uri": temp_dir.url().join("file.tsx").unwrap(),
"version": version,
},
"contentChanges": [
{
"range": {
"start": { "line": 0, "character": 0 },
"end": { "line": 0, "character": 0 },
},
"text": "",
},
],
}),
);
diagnostics = client.read_diagnostics();
}
assert_eq!(diagnostics.all(), vec![]);
client.shutdown();
}
#[ignore = "https://github.com/denoland/deno/issues/21770"]
#[test]
fn lsp_jsx_import_source_package_json_automatic_cache() {
let context = TestContextBuilder::new()
.use_http_server()
.use_temp_cwd()
.build();
let temp_dir = context.temp_dir();
temp_dir.write(
"deno.json",
json!({
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact",
},
"nodeModulesDir": false,
})
.to_string(),
);
temp_dir.write(
"package.json",
json!({
"dependencies": {
"preact": "^10.19.6",
},
})
.to_string(),
);
let mut client = context.new_lsp_command().build();
client.initialize_default();
let mut diagnostics = client.did_open(json!({
"textDocument": {
"uri": temp_dir.url().join("file.tsx").unwrap(),
"languageId": "typescriptreact",
"version": 1,
"text": "
export function Foo() {
return <div></div>;
}
",
},
}));
// The caching is done on an asynchronous task spawned after init, so there's
// a chance it wasn't done in time and we need to wait for another batch of
// diagnostics.
let mut version = 1;
while !diagnostics.all().is_empty() {
std::thread::sleep(std::time::Duration::from_millis(50));
// The post-cache diagnostics update triggers inconsistently on CI for some
// reason. Force it with this notification.
version += 1;
client.write_notification(
"textDocument/didChange",
json!({
"textDocument": {
"uri": temp_dir.url().join("file.tsx").unwrap(),
"version": version,
},
"contentChanges": [
{
"range": {
"start": { "line": 0, "character": 0 },
"end": { "line": 0, "character": 0 },
},
"text": "",
},
],
}),
);
diagnostics = client.read_diagnostics();
}
assert_eq!(json!(diagnostics.all()), json!([]));
client.shutdown();
}
#[test]
fn lsp_jsx_import_source_byonm_preact() {
let context = TestContextBuilder::new()