mirror of
https://github.com/denoland/deno.git
synced 2025-03-09 21:57:40 -04:00
perf(lsp): lazily start the ts server (#28392)
This commit is contained in:
parent
e579440170
commit
0ef3f6ba88
4 changed files with 86 additions and 60 deletions
|
@ -2022,7 +2022,6 @@ let c: number = "a";
|
|||
.await;
|
||||
let snapshot = Arc::new(snapshot);
|
||||
let ts_server = TsServer::new(Default::default());
|
||||
ts_server.start(None).unwrap();
|
||||
|
||||
// test enabled
|
||||
{
|
||||
|
|
|
@ -213,9 +213,7 @@ pub struct Inner {
|
|||
registered_semantic_tokens_capabilities: bool,
|
||||
pub resolver: Arc<LspResolver>,
|
||||
task_queue: LanguageServerTaskQueue,
|
||||
/// A memoized version of fixable diagnostic codes retrieved from TypeScript.
|
||||
ts_fixable_diagnostics: Vec<String>,
|
||||
/// An abstraction that handles interactions with TypeScript.
|
||||
ts_fixable_diagnostics: tokio::sync::OnceCell<Vec<String>>,
|
||||
pub ts_server: Arc<TsServer>,
|
||||
/// A map of specifiers and URLs used to translate over the LSP.
|
||||
pub url_map: urls::LspUrlMap,
|
||||
|
@ -621,6 +619,19 @@ impl Inner {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn ts_fixable_diagnostics(&self) -> &Vec<String> {
|
||||
self
|
||||
.ts_fixable_diagnostics
|
||||
.get_or_init(|| async {
|
||||
self
|
||||
.ts_server
|
||||
.get_supported_code_fixes(self.snapshot())
|
||||
.await
|
||||
.unwrap()
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn update_tracing(&mut self) {
|
||||
let tracing =
|
||||
self
|
||||
|
@ -777,7 +788,7 @@ impl Inner {
|
|||
|
||||
// lspower::LanguageServer methods. This file's LanguageServer delegates to us.
|
||||
impl Inner {
|
||||
async fn initialize(
|
||||
fn initialize(
|
||||
&mut self,
|
||||
params: InitializeParams,
|
||||
) -> LspResult<InitializeResult> {
|
||||
|
@ -862,26 +873,13 @@ impl Inner {
|
|||
}
|
||||
|
||||
self.diagnostics_server.start();
|
||||
if let Err(e) = self
|
||||
self
|
||||
.ts_server
|
||||
.start(self.config.internal_inspect().to_address())
|
||||
{
|
||||
lsp_warn!("{}", e);
|
||||
self.client.show_message(MessageType::ERROR, e);
|
||||
return Err(tower_lsp::jsonrpc::Error::internal_error());
|
||||
};
|
||||
.set_inspector_server_addr(self.config.internal_inspect().to_address());
|
||||
|
||||
self.update_tracing();
|
||||
self.update_debug_flag();
|
||||
|
||||
if capabilities.code_action_provider.is_some() {
|
||||
let fixable_diagnostics = self
|
||||
.ts_server
|
||||
.get_supported_code_fixes(self.snapshot())
|
||||
.await?;
|
||||
self.ts_fixable_diagnostics = fixable_diagnostics;
|
||||
}
|
||||
|
||||
if capabilities.semantic_tokens_provider.is_some() {
|
||||
self.registered_semantic_tokens_capabilities = true;
|
||||
}
|
||||
|
@ -1746,6 +1744,7 @@ impl Inner {
|
|||
let line_index = asset_or_doc.line_index();
|
||||
|
||||
// QuickFix
|
||||
let ts_fixable_diagnosics = self.ts_fixable_diagnostics().await;
|
||||
let fixable_diagnostics: Vec<&Diagnostic> = params
|
||||
.context
|
||||
.diagnostics
|
||||
|
@ -1754,10 +1753,10 @@ impl Inner {
|
|||
Some(source) => match source.as_str() {
|
||||
"deno-ts" => match &d.code {
|
||||
Some(NumberOrString::String(code)) => {
|
||||
self.ts_fixable_diagnostics.contains(code)
|
||||
ts_fixable_diagnosics.contains(code)
|
||||
}
|
||||
Some(NumberOrString::Number(code)) => {
|
||||
self.ts_fixable_diagnostics.contains(&code.to_string())
|
||||
ts_fixable_diagnosics.contains(&code.to_string())
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
|
@ -3399,6 +3398,9 @@ impl Inner {
|
|||
params: RenameFilesParams,
|
||||
token: &CancellationToken,
|
||||
) -> LspResult<Option<WorkspaceEdit>> {
|
||||
if !self.ts_server.is_started() {
|
||||
return Ok(None);
|
||||
}
|
||||
let mut changes = vec![];
|
||||
for rename in params.files {
|
||||
let old_specifier = self.url_map.uri_to_specifier(
|
||||
|
@ -3461,6 +3463,10 @@ impl Inner {
|
|||
params: WorkspaceSymbolParams,
|
||||
token: &CancellationToken,
|
||||
) -> LspResult<Option<Vec<SymbolInformation>>> {
|
||||
if !self.ts_server.is_started() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mark = self.performance.mark_with_args("lsp.symbol", ¶ms);
|
||||
|
||||
let navigate_to_items = self
|
||||
|
@ -3588,7 +3594,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
|
|||
&self,
|
||||
params: InitializeParams,
|
||||
) -> LspResult<InitializeResult> {
|
||||
self.inner.write().await.initialize(params).await
|
||||
self.inner.write().await.initialize(params)
|
||||
}
|
||||
|
||||
async fn initialized(&self, _: InitializedParams) {
|
||||
|
|
|
@ -19,7 +19,6 @@ use std::thread;
|
|||
use dashmap::DashMap;
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context as _;
|
||||
use deno_core::convert::Smi;
|
||||
use deno_core::convert::ToV8;
|
||||
use deno_core::error::AnyError;
|
||||
|
@ -245,9 +244,11 @@ pub struct TsServer {
|
|||
sender: mpsc::UnboundedSender<Request>,
|
||||
receiver: Mutex<Option<mpsc::UnboundedReceiver<Request>>>,
|
||||
pub specifier_map: Arc<TscSpecifierMap>,
|
||||
inspector_server_addr: Mutex<Option<String>>,
|
||||
inspector_server: Mutex<Option<Arc<InspectorServer>>>,
|
||||
pending_change: Mutex<Option<PendingChange>>,
|
||||
enable_tracing: Arc<AtomicBool>,
|
||||
start_once: std::sync::Once,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for TsServer {
|
||||
|
@ -257,7 +258,9 @@ impl std::fmt::Debug for TsServer {
|
|||
.field("sender", &self.sender)
|
||||
.field("receiver", &self.receiver)
|
||||
.field("specifier_map", &self.specifier_map)
|
||||
.field("inspector_server_addr", &self.inspector_server_addr.lock())
|
||||
.field("inspector_server", &self.inspector_server.lock().is_some())
|
||||
.field("start_once", &self.start_once)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -404,9 +407,11 @@ impl TsServer {
|
|||
sender: tx,
|
||||
receiver: Mutex::new(Some(request_rx)),
|
||||
specifier_map: Arc::new(TscSpecifierMap::new()),
|
||||
inspector_server_addr: Mutex::new(None),
|
||||
inspector_server: Mutex::new(None),
|
||||
pending_change: Mutex::new(None),
|
||||
enable_tracing: Default::default(),
|
||||
start_once: std::sync::Once::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,20 +421,28 @@ impl TsServer {
|
|||
.store(enabled, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
pub fn start(
|
||||
&self,
|
||||
inspector_server_addr: Option<String>,
|
||||
) -> Result<(), AnyError> {
|
||||
let maybe_inspector_server = match inspector_server_addr {
|
||||
Some(addr) => {
|
||||
let addr: SocketAddr = addr.parse().with_context(|| {
|
||||
format!("Invalid inspector server address \"{}\"", &addr)
|
||||
})?;
|
||||
let server = InspectorServer::new(addr, "deno-lsp-tsc")?;
|
||||
Some(Arc::new(server))
|
||||
/// This should be called before `self.ensure_started()`.
|
||||
pub fn set_inspector_server_addr(&self, addr: Option<String>) {
|
||||
*self.inspector_server_addr.lock() = addr;
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
pub fn ensure_started(&self) {
|
||||
self.start_once.call_once(|| {
|
||||
let maybe_inspector_server = self
|
||||
.inspector_server_addr
|
||||
.lock()
|
||||
.as_ref()
|
||||
.and_then(|addr| {
|
||||
addr
|
||||
.parse::<SocketAddr>()
|
||||
.inspect_err(|err| {
|
||||
lsp_warn!("Invalid inspector server address: {:#}", err);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.map(|addr| {
|
||||
Arc::new(InspectorServer::new(addr, "deno-lsp-tsc").unwrap())
|
||||
});
|
||||
self
|
||||
.inspector_server
|
||||
.lock()
|
||||
|
@ -449,7 +462,12 @@ impl TsServer {
|
|||
enable_tracing,
|
||||
)
|
||||
});
|
||||
Ok(())
|
||||
lsp_log!("TS server started.");
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is_started(&self) -> bool {
|
||||
self.start_once.is_completed()
|
||||
}
|
||||
|
||||
pub fn project_changed<'a>(
|
||||
|
@ -549,6 +567,9 @@ impl TsServer {
|
|||
|
||||
#[cfg_attr(feature = "lsp-tracing", tracing::instrument(skip_all))]
|
||||
pub async fn cleanup_semantic_cache(&self, snapshot: Arc<StateSnapshot>) {
|
||||
if !self.is_started() {
|
||||
return;
|
||||
}
|
||||
for scope in snapshot
|
||||
.config
|
||||
.tree
|
||||
|
@ -1365,6 +1386,7 @@ impl TsServer {
|
|||
R: de::DeserializeOwned,
|
||||
{
|
||||
use super::trace::SpanExt;
|
||||
self.ensure_started();
|
||||
let context = super::trace::Span::current().context();
|
||||
let mark = self
|
||||
.performance
|
||||
|
@ -5772,7 +5794,6 @@ mod tests {
|
|||
});
|
||||
let performance = Arc::new(Performance::default());
|
||||
let ts_server = TsServer::new(performance);
|
||||
ts_server.start(None).unwrap();
|
||||
ts_server.project_changed(
|
||||
snapshot.clone(),
|
||||
[],
|
||||
|
|
|
@ -11488,13 +11488,11 @@ fn lsp_performance() {
|
|||
"lsp.update_diagnostics_ts",
|
||||
"lsp.update_global_cache",
|
||||
"tsc.host.$getDiagnostics",
|
||||
"tsc.host.$getSupportedCodeFixes",
|
||||
"tsc.host.getQuickInfoAtPosition",
|
||||
"tsc.op.op_is_node_file",
|
||||
"tsc.op.op_load",
|
||||
"tsc.op.op_script_names",
|
||||
"tsc.request.$getDiagnostics",
|
||||
"tsc.request.$getSupportedCodeFixes",
|
||||
"tsc.request.getQuickInfoAtPosition",
|
||||
]
|
||||
);
|
||||
|
@ -15135,6 +15133,7 @@ fn lsp_deno_json_scopes_file_rename_import_edits() {
|
|||
);
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open_file(&file1);
|
||||
let res = client.write_request(
|
||||
"workspace/willRenameFiles",
|
||||
json!({
|
||||
|
@ -15395,6 +15394,7 @@ fn lsp_deno_json_scopes_search_symbol() {
|
|||
);
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open_file(&file1);
|
||||
let res =
|
||||
client.write_request("workspace/symbol", json!({ "query": "someSymbol" }));
|
||||
assert_eq!(
|
||||
|
|
Loading…
Add table
Reference in a new issue