summaryrefslogtreecommitdiff
path: root/cli/lsp/language_server.rs
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2024-05-29 01:26:43 +0100
committerGitHub <noreply@github.com>2024-05-29 01:26:43 +0100
commit14a74600de6f1c206ffe4750f6cb6da59657db8e (patch)
treece593041af972fd31f83fa6b7b50458bc9f689dc /cli/lsp/language_server.rs
parent2024c974b613f94f31559a1b32e2d747c2083e91 (diff)
perf(lsp): lock out requests until init is complete (#23998)
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r--cli/lsp/language_server.rs368
1 files changed, 252 insertions, 116 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 621f45f96..9abefb141 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -31,7 +31,6 @@ use std::sync::Arc;
use tokio::sync::mpsc::unbounded_channel;
use tokio::sync::mpsc::UnboundedReceiver;
use tokio::sync::mpsc::UnboundedSender;
-use tokio_util::sync::CancellationToken;
use tower_lsp::jsonrpc::Error as LspError;
use tower_lsp::jsonrpc::Result as LspResult;
use tower_lsp::lsp_types::request::*;
@@ -105,6 +104,7 @@ use crate::tools::upgrade::upgrade_check_enabled;
use crate::util::fs::remove_dir_all_if_exists;
use crate::util::path::is_importable_ext;
use crate::util::path::to_percent_decoded_str;
+use crate::util::sync::AsyncFlag;
use deno_runtime::fs_util::specifier_to_file_path;
struct LspRootCertStoreProvider(RootCertStore);
@@ -116,10 +116,17 @@ impl RootCertStoreProvider for LspRootCertStoreProvider {
}
#[derive(Debug, Clone)]
-pub struct LanguageServer(
- pub Arc<tokio::sync::RwLock<Inner>>,
- CancellationToken,
-);
+pub struct LanguageServer {
+ pub inner: Arc<tokio::sync::RwLock<Inner>>,
+ /// This is used to block out standard request handling until the complete
+ /// user configuration has been fetched. This is done in the `initialized`
+ /// handler which normally may occur concurrently with those other requests.
+ /// TODO(nayeemrmn): This wouldn't be necessary if LSP allowed
+ /// `workspace/configuration` requests in the `initialize` handler. See:
+ /// https://github.com/Microsoft/language-server-protocol/issues/567#issuecomment-2085131917
+ init_flag: AsyncFlag,
+ shutdown_flag: AsyncFlag,
+}
/// Snapshot of the state used by TSC.
#[derive(Clone, Debug, Default)]
@@ -210,11 +217,12 @@ pub struct Inner {
}
impl LanguageServer {
- pub fn new(client: Client, token: CancellationToken) -> Self {
- Self(
- Arc::new(tokio::sync::RwLock::new(Inner::new(client))),
- token,
- )
+ pub fn new(client: Client, shutdown_flag: AsyncFlag) -> Self {
+ Self {
+ inner: Arc::new(tokio::sync::RwLock::new(Inner::new(client))),
+ init_flag: Default::default(),
+ shutdown_flag,
+ }
}
/// Similar to `deno cache` on the command line, where modules will be cached
@@ -225,6 +233,9 @@ impl LanguageServer {
referrer: ModuleSpecifier,
force_global_cache: bool,
) -> LspResult<Option<Value>> {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
async fn create_graph_for_caching(
cli_options: CliOptions,
roots: Vec<ModuleSpecifier>,
@@ -272,13 +283,13 @@ impl LanguageServer {
// prepare the cache inside the lock
let maybe_prepare_cache_result = {
- let mut inner = self.0.write().await; // ensure dropped
+ let mut inner = self.inner.write().await;
match inner.prepare_cache(specifiers, referrer, force_global_cache) {
Ok(maybe_cache_result) => maybe_cache_result,
Err(err) => {
lsp_warn!("Error preparing caching: {:#}", err);
self
- .0
+ .inner
.read()
.await
.client
@@ -298,7 +309,7 @@ impl LanguageServer {
if let Err(err) = handle.await.unwrap() {
lsp_warn!("Error caching: {:#}", err);
self
- .0
+ .inner
.read()
.await
.client
@@ -306,7 +317,7 @@ impl LanguageServer {
}
// now get the lock back to update with the new information
- let mut inner = self.0.write().await;
+ let mut inner = self.inner.write().await;
inner.resolver.did_cache();
inner.refresh_npm_specifiers().await;
inner.diagnostics_server.invalidate_all();
@@ -327,9 +338,12 @@ impl LanguageServer {
pub async fn latest_diagnostic_batch_index_request(
&self,
) -> LspResult<Option<Value>> {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
Ok(
self
- .0
+ .inner
.read()
.await
.diagnostics_server
@@ -339,18 +353,27 @@ impl LanguageServer {
}
pub async fn performance_request(&self) -> LspResult<Option<Value>> {
- Ok(Some(self.0.read().await.get_performance()))
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ Ok(Some(self.inner.read().await.get_performance()))
}
pub async fn task_definitions(&self) -> LspResult<Vec<TaskDefinition>> {
- self.0.read().await.task_definitions()
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.task_definitions()
}
pub async fn test_run_request(
&self,
params: Option<Value>,
) -> LspResult<Option<Value>> {
- let inner = self.0.read().await;
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ let inner = self.inner.read().await;
if let Some(testing_server) = &inner.maybe_testing_server {
match params.map(serde_json::from_value) {
Some(Ok(params)) => {
@@ -370,7 +393,11 @@ impl LanguageServer {
&self,
params: Option<Value>,
) -> LspResult<Option<Value>> {
- if let Some(testing_server) = &self.0.read().await.maybe_testing_server {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ if let Some(testing_server) = &self.inner.read().await.maybe_testing_server
+ {
match params.map(serde_json::from_value) {
Some(Ok(params)) => testing_server.run_cancel_request(params),
Some(Err(err)) => Err(LspError::invalid_params(err.to_string())),
@@ -385,10 +412,13 @@ impl LanguageServer {
&self,
params: Option<Value>,
) -> LspResult<Option<Value>> {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
match params.map(serde_json::from_value) {
Some(Ok(params)) => Ok(Some(
serde_json::to_value(
- self.0.read().await.virtual_text_document(params)?,
+ self.inner.read().await.virtual_text_document(params)?,
)
.map_err(|err| {
error!(
@@ -405,11 +435,11 @@ impl LanguageServer {
pub async fn refresh_configuration(&self) {
let (client, folders, capable) = {
- let ls = self.0.read().await;
+ let inner = self.inner.read().await;
(
- ls.client.clone(),
- ls.config.workspace_folders.clone(),
- ls.config.client_capabilities.workspace_configuration,
+ inner.client.clone(),
+ inner.config.workspace_folders.clone(),
+ inner.config.client_capabilities.workspace_configuration,
)
};
if capable {
@@ -433,8 +463,10 @@ impl LanguageServer {
for (folder_uri, _) in &folders {
folder_settings.push((folder_uri.clone(), configs.next().unwrap()));
}
- let mut ls = self.0.write().await;
- ls.config.set_workspace_settings(unscoped, folder_settings);
+ let mut inner = self.inner.write().await;
+ inner
+ .config
+ .set_workspace_settings(unscoped, folder_settings);
}
}
}
@@ -751,10 +783,6 @@ impl Inner {
};
self.update_debug_flag();
- self.update_global_cache().await;
- self.refresh_workspace_files();
- self.refresh_config_tree().await;
- self.update_cache();
if capabilities.code_action_provider.is_some() {
let fixable_diagnostics = self
@@ -947,10 +975,14 @@ impl Inner {
}
async fn refresh_resolver(&mut self) {
- self.resolver = self
- .resolver
- .with_new_config(&self.config, &self.cache, Some(&self.http_client))
- .await;
+ self.resolver = Arc::new(
+ LspResolver::from_config(
+ &self.config,
+ &self.cache,
+ Some(&self.http_client),
+ )
+ .await,
+ );
}
async fn refresh_documents_config(&mut self) {
@@ -968,10 +1000,6 @@ impl Inner {
self.project_changed([], true);
}
- fn shutdown(&self) -> LspResult<()> {
- Ok(())
- }
-
async fn did_open(&mut self, params: DidOpenTextDocumentParams) {
let mark = self.performance.mark_with_args("lsp.did_open", &params);
if params.text_document.uri.scheme() == "deno" {
@@ -1149,7 +1177,17 @@ impl Inner {
self.workspace_files_hash = 0;
self.refresh_workspace_files();
self.refresh_config_tree().await;
+ self.update_cache();
self.refresh_resolver().await;
+ self.refresh_documents_config().await;
+ self.project_changed(
+ changes.iter().map(|(s, _)| (s, ChangeKind::Modified)),
+ false,
+ );
+ self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
+ self.diagnostics_server.invalidate_all();
+ self.send_diagnostics_update();
+ self.send_testing_update();
deno_config_changes.extend(changes.iter().filter_map(|(s, e)| {
self.config.tree.watched_file_type(s).and_then(|t| {
let configuration_type = match t.1 {
@@ -1178,15 +1216,6 @@ impl Inner {
},
);
}
- self.refresh_documents_config().await;
- self.diagnostics_server.invalidate_all();
- self.project_changed(
- changes.iter().map(|(s, _)| (s, ChangeKind::Modified)),
- false,
- );
- self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
- self.send_diagnostics_update();
- self.send_testing_update();
}
self.performance.measure(mark);
}
@@ -1254,9 +1283,8 @@ impl Inner {
}
let document =
file_referrer.and_then(|r| self.documents.get_or_load(&specifier, &r));
- let document = match document {
- Some(doc) if doc.is_open() => doc,
- _ => return Ok(None),
+ let Some(document) = document else {
+ return Ok(None);
};
// Detect vendored paths. Vendor file URLs will normalize to their remote
// counterparts, but for formatting we want to favour the file URL.
@@ -2812,6 +2840,9 @@ impl tower_lsp::LanguageServer for LanguageServer {
&self,
params: ExecuteCommandParams,
) -> LspResult<Option<Value>> {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
if params.command == "deno.cache" {
#[derive(Default, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -2828,7 +2859,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
.cache(specifiers, referrer, options.force_global_cache)
.await
} else if params.command == "deno.reloadImportRegistries" {
- self.0.write().await.reload_import_registries().await
+ self.inner.write().await.reload_import_registries().await
} else {
Ok(None)
}
@@ -2838,14 +2869,25 @@ impl tower_lsp::LanguageServer for LanguageServer {
&self,
params: InitializeParams,
) -> LspResult<InitializeResult> {
- self.0.write().await.initialize(params).await
+ self.inner.write().await.initialize(params).await
}
async fn initialized(&self, _: InitializedParams) {
+ self.refresh_configuration().await;
let mut registrations = Vec::with_capacity(2);
let (client, http_client) = {
- let mut ls = self.0.write().await;
- if ls
+ let mut inner = self.inner.write().await;
+ init_log_file(inner.config.log_file());
+ inner.update_debug_flag();
+ inner.update_global_cache().await;
+ inner.refresh_workspace_files();
+ inner.refresh_config_tree().await;
+ inner.update_cache();
+ inner.refresh_resolver().await;
+ inner.refresh_documents_config().await;
+ inner.task_queue.start(self.clone());
+ self.init_flag.raise();
+ if inner
.config
.client_capabilities
.workspace_did_change_watched_files
@@ -2867,7 +2909,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
register_options: Some(serde_json::to_value(options).unwrap()),
});
}
- if ls.config.client_capabilities.workspace_will_rename_files {
+ if inner.config.client_capabilities.workspace_will_rename_files {
let options = FileOperationRegistrationOptions {
filters: vec![FileOperationFilter {
scheme: Some("file".to_string()),
@@ -2885,17 +2927,17 @@ impl tower_lsp::LanguageServer for LanguageServer {
});
}
- if ls.config.client_capabilities.testing_api {
+ if inner.config.client_capabilities.testing_api {
let test_server = testing::TestServer::new(
- ls.client.clone(),
- ls.performance.clone(),
- ls.config.root_uri().cloned(),
+ inner.client.clone(),
+ inner.performance.clone(),
+ inner.config.root_uri().cloned(),
);
- ls.maybe_testing_server = Some(test_server);
+ inner.maybe_testing_server = Some(test_server);
}
let mut config_events = vec![];
- for (scope_uri, config_data) in ls.config.tree.data_by_scope().iter() {
+ for (scope_uri, config_data) in inner.config.tree.data_by_scope().iter() {
if let Some(config_file) = &config_data.config_file {
config_events.push(lsp_custom::DenoConfigurationChangeEvent {
scope_uri: scope_uri.clone(),
@@ -2914,14 +2956,16 @@ impl tower_lsp::LanguageServer for LanguageServer {
}
}
if !config_events.is_empty() {
- ls.client.send_did_change_deno_configuration_notification(
- lsp_custom::DidChangeDenoConfigurationNotificationParams {
- changes: config_events,
- },
- );
+ inner
+ .client
+ .send_did_change_deno_configuration_notification(
+ lsp_custom::DidChangeDenoConfigurationNotificationParams {
+ changes: config_events,
+ },
+ );
}
- (ls.client.clone(), ls.http_client.clone())
+ (inner.client.clone(), inner.http_client.clone())
};
for registration in registrations {
@@ -2934,18 +2978,6 @@ impl tower_lsp::LanguageServer for LanguageServer {
}
}
- self.refresh_configuration().await;
-
- {
- let mut ls = self.0.write().await;
- init_log_file(ls.config.log_file());
- ls.refresh_resolver().await;
- ls.refresh_documents_config().await;
- ls.diagnostics_server.invalidate_all();
- ls.send_diagnostics_update();
- ls.task_queue.start(self.clone());
- };
-
if upgrade_check_enabled() {
// spawn to avoid lsp send/sync requirement, but also just
// to ensure this initialized method returns quickly
@@ -2972,38 +3004,53 @@ impl tower_lsp::LanguageServer for LanguageServer {
}
async fn shutdown(&self) -> LspResult<()> {
- self.1.cancel();
- self.0.write().await.shutdown()
+ self.shutdown_flag.raise();
+ Ok(())
}
async fn did_open(&self, params: DidOpenTextDocumentParams) {
- self.0.write().await.did_open(params).await;
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.write().await.did_open(params).await;
}
async fn did_change(&self, params: DidChangeTextDocumentParams) {
- self.0.write().await.did_change(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.write().await.did_change(params).await
}
async fn did_save(&self, params: DidSaveTextDocumentParams) {
- self.0.write().await.did_save(params);
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.write().await.did_save(params);
}
async fn did_close(&self, params: DidCloseTextDocumentParams) {
- self.0.write().await.did_close(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.write().await.did_close(params).await
}
async fn did_change_configuration(
&self,
params: DidChangeConfigurationParams,
) {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
let mark = {
- let inner = self.0.read().await;
+ let inner = self.inner.read().await;
inner
.performance
.mark_with_args("lsp.did_change_configuration", &params)
};
self.refresh_configuration().await;
- let mut inner = self.0.write().await;
+ let mut inner = self.inner.write().await;
if !inner.config.client_capabilities.workspace_configuration {
let config = params.settings.as_object().map(|settings| {
let deno =
@@ -3035,15 +3082,26 @@ impl tower_lsp::LanguageServer for LanguageServer {
&self,
params: DidChangeWatchedFilesParams,
) {
- self.0.write().await.did_change_watched_files(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self
+ .inner
+ .write()
+ .await
+ .did_change_watched_files(params)
+ .await
}
async fn did_change_workspace_folders(
&self,
params: DidChangeWorkspaceFoldersParams,
) {
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
let mark = {
- let mut inner = self.0.write().await;
+ let mut inner = self.inner.write().await;
let mark = inner
.performance
.mark_with_args("lsp.did_change_workspace_folders", &params);
@@ -3070,7 +3128,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
mark
};
self.refresh_configuration().await;
- let mut inner = self.0.write().await;
+ let mut inner = self.inner.write().await;
inner.refresh_workspace_files();
inner.refresh_config_tree().await;
inner.refresh_resolver().await;
@@ -3085,176 +3143,254 @@ impl tower_lsp::LanguageServer for LanguageServer {
&self,
params: DocumentSymbolParams,
) -> LspResult<Option<DocumentSymbolResponse>> {
- self.0.read().await.document_symbol(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.document_symbol(params).await
}
async fn formatting(
&self,
params: DocumentFormattingParams,
) -> LspResult<Option<Vec<TextEdit>>> {
- self.0.read().await.formatting(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.formatting(params).await
}
async fn hover(&self, params: HoverParams) -> LspResult<Option<Hover>> {
- self.0.read().await.hover(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.hover(params).await
}
async fn inlay_hint(
&self,
params: InlayHintParams,
) -> LspResult<Option<Vec<InlayHint>>> {
- self.0.read().await.inlay_hint(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.inlay_hint(params).await
}
async fn code_action(
&self,
params: CodeActionParams,
) -> LspResult<Option<CodeActionResponse>> {
- self.0.read().await.code_action(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.code_action(params).await
}
async fn code_action_resolve(
&self,
params: CodeAction,
) -> LspResult<CodeAction> {
- self.0.read().await.code_action_resolve(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.code_action_resolve(params).await
}
async fn code_lens(
&self,
params: CodeLensParams,
) -> LspResult<Option<Vec<CodeLens>>> {
- self.0.read().await.code_lens(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.code_lens(params).await
}
async fn code_lens_resolve(&self, params: CodeLens) -> LspResult<CodeLens> {
- self.0.read().await.code_lens_resolve(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.code_lens_resolve(params).await
}
async fn document_highlight(
&self,
params: DocumentHighlightParams,
) -> LspResult<Option<Vec<DocumentHighlight>>> {
- self.0.read().await.document_highlight(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.document_highlight(params).await
}
async fn references(
&self,
params: ReferenceParams,
) -> LspResult<Option<Vec<Location>>> {
- self.0.read().await.references(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.references(params).await
}
async fn goto_definition(
&self,
params: GotoDefinitionParams,
) -> LspResult<Option<GotoDefinitionResponse>> {
- self.0.read().await.goto_definition(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.goto_definition(params).await
}
async fn goto_type_definition(
&self,
params: GotoTypeDefinitionParams,
) -> LspResult<Option<GotoTypeDefinitionResponse>> {
- self.0.read().await.goto_type_definition(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.goto_type_definition(params).await
}
async fn completion(
&self,
params: CompletionParams,
) -> LspResult<Option<CompletionResponse>> {
- self.0.read().await.completion(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.completion(params).await
}
async fn completion_resolve(
&self,
params: CompletionItem,
) -> LspResult<CompletionItem> {
- self.0.read().await.completion_resolve(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.completion_resolve(params).await
}
async fn goto_implementation(
&self,
params: GotoImplementationParams,
) -> LspResult<Option<GotoImplementationResponse>> {
- self.0.read().await.goto_implementation(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.goto_implementation(params).await
}
async fn folding_range(
&self,
params: FoldingRangeParams,
) -> LspResult<Option<Vec<FoldingRange>>> {
- self.0.read().await.folding_range(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.folding_range(params).await
}
async fn incoming_calls(
&self,
params: CallHierarchyIncomingCallsParams,
) -> LspResult<Option<Vec<CallHierarchyIncomingCall>>> {
- self.0.read().await.incoming_calls(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.incoming_calls(params).await
}
async fn outgoing_calls(
&self,
params: CallHierarchyOutgoingCallsParams,
) -> LspResult<Option<Vec<CallHierarchyOutgoingCall>>> {
- self.0.read().await.outgoing_calls(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.outgoing_calls(params).await
}
async fn prepare_call_hierarchy(
&self,
params: CallHierarchyPrepareParams,
) -> LspResult<Option<Vec<CallHierarchyItem>>> {
- self.0.read().await.prepare_call_hierarchy(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.prepare_call_hierarchy(params).await
}
async fn rename(
&self,
params: RenameParams,
) -> LspResult<Option<WorkspaceEdit>> {
- self.0.read().await.rename(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.rename(params).await
}
async fn selection_range(
&self,
params: SelectionRangeParams,
) -> LspResult<Option<Vec<SelectionRange>>> {
- self.0.read().await.selection_range(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.selection_range(params).await
}
async fn semantic_tokens_full(
&self,
params: SemanticTokensParams,
) -> LspResult<Option<SemanticTokensResult>> {
- self.0.read().await.semantic_tokens_full(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.semantic_tokens_full(params).await
}
async fn semantic_tokens_range(
&self,
params: SemanticTokensRangeParams,
) -> LspResult<Option<SemanticTokensRangeResult>> {
- self.0.read().await.semantic_tokens_range(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.semantic_tokens_range(params).await
}
async fn signature_help(
&self,
params: SignatureHelpParams,
) -> LspResult<Option<SignatureHelp>> {
- self.0.read().await.signature_help(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.signature_help(params).await
}
async fn will_rename_files(
&self,
params: RenameFilesParams,
) -> LspResult<Option<WorkspaceEdit>> {
- self.0.read().await.will_rename_files(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.will_rename_files(params).await
}
async fn symbol(
&self,
params: WorkspaceSymbolParams,
) -> LspResult<Option<Vec<SymbolInformation>>> {
- self.0.read().await.symbol(params).await
+ if !self.init_flag.is_raised() {
+ self.init_flag.wait_raised().await;
+ }
+ self.inner.read().await.symbol(params).await
}
}