summaryrefslogtreecommitdiff
path: root/cli/lsp
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2024-04-17 21:40:42 +0100
committerGitHub <noreply@github.com>2024-04-17 21:40:42 +0100
commit24fa5c784a7a4731ba8864e52977857959c580ed (patch)
tree692fea409e70e5b4e0885ee4acab27b7d37ca07e /cli/lsp
parent2dc3f6f57a5e0fe68f3265c6a3a89cc37661ff32 (diff)
perf(lsp): release unused documents (#23398)
Diffstat (limited to 'cli/lsp')
-rw-r--r--cli/lsp/documents.rs5
-rw-r--r--cli/lsp/language_server.rs29
-rw-r--r--cli/lsp/tsc.rs39
3 files changed, 54 insertions, 19 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 154dfb5dc..8a98b8dd5 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -1015,6 +1015,11 @@ impl Documents {
Ok(())
}
+ pub fn release(&self, specifier: &ModuleSpecifier) {
+ self.file_system_docs.remove_document(specifier);
+ self.file_system_docs.set_dirty(true);
+ }
+
/// Return `true` if the provided specifier can be resolved to a document,
/// otherwise `false`.
pub fn contains_import(
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 86d7d65c5..cba8eb01c 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -364,14 +364,11 @@ impl LanguageServer {
.client
.show_message(MessageType::WARNING, err);
}
- {
- let mut inner = self.0.write().await;
- let lockfile = inner.config.tree.root_lockfile().cloned();
- inner.documents.refresh_lockfile(lockfile);
- inner.refresh_npm_specifiers().await;
- }
- // now refresh the data in a read
- self.0.read().await.post_cache(result.mark).await;
+ let mut inner = self.0.write().await;
+ let lockfile = inner.config.tree.root_lockfile().cloned();
+ inner.documents.refresh_lockfile(lockfile);
+ inner.refresh_npm_specifiers().await;
+ inner.post_cache(result.mark).await;
}
Ok(Some(json!(true)))
}
@@ -1421,7 +1418,16 @@ impl Inner {
self.recreate_npm_services_if_necessary().await;
self.refresh_documents_config().await;
self.diagnostics_server.invalidate_all();
- self.ts_server.restart(self.snapshot()).await;
+ self
+ .project_changed(
+ &changes
+ .iter()
+ .map(|(s, _)| (s, ChangeKind::Modified))
+ .collect::<Vec<_>>(),
+ false,
+ )
+ .await;
+ self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
self.send_diagnostics_update();
self.send_testing_update();
}
@@ -3544,13 +3550,14 @@ impl Inner {
}))
}
- async fn post_cache(&self, mark: PerformanceMark) {
+ async fn post_cache(&mut self, mark: PerformanceMark) {
// Now that we have dependencies loaded, we need to re-analyze all the files.
// For that we're invalidating all the existing diagnostics and restarting
// the language server for TypeScript (as it might hold to some stale
// documents).
self.diagnostics_server.invalidate_all();
- self.ts_server.restart(self.snapshot()).await;
+ self.project_changed(&[], false).await;
+ self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
self.send_diagnostics_update();
self.send_testing_update();
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index d36b59821..5b1136d90 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -356,6 +356,21 @@ impl TsServer {
Ok(diagnostics_map)
}
+ pub async fn cleanup_semantic_cache(&self, snapshot: Arc<StateSnapshot>) {
+ let req = TscRequest {
+ method: "cleanupSemanticCache",
+ args: json!([]),
+ };
+ self
+ .request::<()>(snapshot, req)
+ .await
+ .map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ .ok();
+ }
+
pub async fn find_references(
&self,
snapshot: Arc<StateSnapshot>,
@@ -1010,14 +1025,6 @@ impl TsServer {
})
}
- pub async fn restart(&self, snapshot: Arc<StateSnapshot>) {
- let req = TscRequest {
- method: "$restart",
- args: json!([]),
- };
- self.request::<bool>(snapshot, req).await.unwrap();
- }
-
async fn request<R>(
&self,
snapshot: Arc<StateSnapshot>,
@@ -4032,6 +4039,21 @@ fn op_load<'s>(
Ok(serialized)
}
+#[op2(fast)]
+fn op_release(
+ state: &mut OpState,
+ #[string] specifier: &str,
+) -> Result<(), AnyError> {
+ let state = state.borrow_mut::<State>();
+ let mark = state
+ .performance
+ .mark_with_args("tsc.op.op_release", specifier);
+ let specifier = state.specifier_map.normalize(specifier)?;
+ state.state_snapshot.documents.release(&specifier);
+ state.performance.measure(mark);
+ Ok(())
+}
+
#[op2]
#[serde]
fn op_resolve(
@@ -4244,6 +4266,7 @@ deno_core::extension!(deno_tsc,
op_is_cancelled,
op_is_node_file,
op_load,
+ op_release,
op_resolve,
op_respond,
op_script_names,