summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2024-09-17 18:29:19 +0100
committerGitHub <noreply@github.com>2024-09-17 18:29:19 +0100
commitf360cae9dd1150c1ca02d51631ddaddb5bf871ab (patch)
tree8c5eb03138afda0c30b8d24fce092ad1474149a6
parentd4a06251c54fc004e189469e493b1261be200300 (diff)
fix(lsp): properly resolve jsxImportSource for caching (#25688)
-rw-r--r--cli/lsp/language_server.rs26
-rw-r--r--tests/integration/lsp_tests.rs108
2 files changed, 114 insertions, 20 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index d025d35a8..c859abc02 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -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);
}
diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs
index 095cbee98..f2c40f8ea 100644
--- a/tests/integration/lsp_tests.rs
+++ b/tests/integration/lsp_tests.rs
@@ -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()