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:
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.
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue