mirror of
https://github.com/denoland/deno.git
synced 2025-09-27 04:39:10 +00:00
fix(lsp): properly resolve jsxImportSource for caching (#25688)
This commit is contained in:
parent
d4a06251c5
commit
f360cae9dd
2 changed files with 114 additions and 20 deletions
|
@ -1,6 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use base64::Engine;
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_config::workspace::WorkspaceDirectory;
|
use deno_config::workspace::WorkspaceDirectory;
|
||||||
use deno_config::workspace::WorkspaceDiscoverOptions;
|
use deno_config::workspace::WorkspaceDiscoverOptions;
|
||||||
|
@ -968,16 +967,27 @@ impl Inner {
|
||||||
(|| {
|
(|| {
|
||||||
let compiler_options = config_file.to_compiler_options().ok()?.options;
|
let compiler_options = config_file.to_compiler_options().ok()?.options;
|
||||||
let jsx_import_source = compiler_options.get("jsxImportSource")?;
|
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 referrer = config_file.specifier.clone();
|
||||||
let specifier = Url::parse(&format!(
|
let specifier = format!("{jsx_import_source}/jsx-runtime");
|
||||||
"data:application/typescript;base64,{}",
|
|
||||||
base64::engine::general_purpose::STANDARD
|
|
||||||
.encode(format!("import '{jsx_import_source}/jsx-runtime';"))
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
self.task_queue.queue_task(Box::new(|ls: LanguageServer| {
|
self.task_queue.queue_task(Box::new(|ls: LanguageServer| {
|
||||||
spawn(async move {
|
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 {
|
if let Err(err) = ls.cache(vec![specifier], referrer, false).await {
|
||||||
lsp_warn!("{:#}", err);
|
lsp_warn!("{:#}", err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11659,11 +11659,67 @@ fn lsp_jsx_import_source_config_file_automatic_cache() {
|
||||||
// The caching is done on an asynchronous task spawned after init, so there's
|
// 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
|
// a chance it wasn't done in time and we need to wait for another batch of
|
||||||
// diagnostics.
|
// diagnostics.
|
||||||
|
let mut version = 1;
|
||||||
while !diagnostics.all().is_empty() {
|
while !diagnostics.all().is_empty() {
|
||||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||||
// The post-cache diagnostics update triggers inconsistently on CI for some
|
// The post-cache diagnostics update triggers inconsistently on CI for some
|
||||||
// reason. Force it with this notification.
|
// reason. Force it with this notification.
|
||||||
diagnostics = client.did_open(json!({
|
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": {
|
"textDocument": {
|
||||||
"uri": temp_dir.url().join("file.tsx").unwrap(),
|
"uri": temp_dir.url().join("file.tsx").unwrap(),
|
||||||
"languageId": "typescriptreact",
|
"languageId": "typescriptreact",
|
||||||
|
@ -11675,8 +11731,36 @@ 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.
|
||||||
|
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![]);
|
assert_eq!(json!(diagnostics.all()), json!([]));
|
||||||
client.shutdown();
|
client.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue