@@ -106,7 +106,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn language_server_initialization_options(
@@ -131,7 +131,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn language_server_workspace_configuration(
@@ -154,7 +154,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn language_server_additional_initialization_options(
@@ -179,7 +179,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn language_server_additional_workspace_configuration(
@@ -204,7 +204,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn labels_for_completions(
@@ -230,7 +230,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn labels_for_symbols(
@@ -256,7 +256,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn complete_slash_command_argument(
@@ -275,7 +275,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn run_slash_command(
@@ -301,7 +301,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn context_server_command(
@@ -320,7 +320,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn context_server_configuration(
@@ -347,7 +347,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn suggest_docs_packages(&self, provider: Arc<str>) -> Result<Vec<String>> {
@@ -362,7 +362,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn index_docs(
@@ -388,7 +388,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn get_dap_binary(
@@ -410,7 +410,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn dap_request_kind(
&self,
@@ -427,7 +427,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn dap_config_to_scenario(&self, config: ZedDebugConfig) -> Result<DebugScenario> {
@@ -441,7 +441,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn dap_locator_create_scenario(
@@ -465,7 +465,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
async fn run_dap_locator(
&self,
@@ -481,7 +481,7 @@ impl extension::Extension for WasmExtension {
}
.boxed()
})
- .await
+ .await?
}
}
@@ -761,7 +761,7 @@ impl WasmExtension {
.with_context(|| format!("failed to load wasm extension {}", manifest.id))
}
- pub async fn call<T, Fn>(&self, f: Fn) -> T
+ pub async fn call<T, Fn>(&self, f: Fn) -> Result<T>
where
T: 'static + Send,
Fn: 'static
@@ -777,14 +777,15 @@ impl WasmExtension {
}
.boxed()
}))
- .unwrap_or_else(|_| {
- panic!(
+ .map_err(|_| {
+ anyhow!(
"wasm extension channel should not be closed yet, extension {} (id {})",
- self.manifest.name, self.manifest.id,
+ self.manifest.name,
+ self.manifest.id,
)
- });
- return_rx.await.unwrap_or_else(|_| {
- panic!(
+ })?;
+ return_rx.await.with_context(|| {
+ format!(
"wasm extension channel, extension {} (id {})",
self.manifest.name, self.manifest.id,
)
@@ -7393,21 +7393,23 @@ impl LspStore {
}
pub(crate) async fn refresh_workspace_configurations(
- this: &WeakEntity<Self>,
+ lsp_store: &WeakEntity<Self>,
fs: Arc<dyn Fs>,
cx: &mut AsyncApp,
) {
maybe!(async move {
- let servers = this
- .update(cx, |this, cx| {
- let Some(local) = this.as_local() else {
+ let mut refreshed_servers = HashSet::default();
+ let servers = lsp_store
+ .update(cx, |lsp_store, cx| {
+ let toolchain_store = lsp_store.toolchain_store(cx);
+ let Some(local) = lsp_store.as_local() else {
return Vec::default();
};
local
.language_server_ids
.iter()
.flat_map(|((worktree_id, _), server_ids)| {
- let worktree = this
+ let worktree = lsp_store
.worktree_store
.read(cx)
.worktree_for_id(*worktree_id, cx);
@@ -7423,43 +7425,54 @@ impl LspStore {
)
});
- server_ids.iter().filter_map(move |server_id| {
+ let fs = fs.clone();
+ let toolchain_store = toolchain_store.clone();
+ server_ids.iter().filter_map(|server_id| {
+ let delegate = delegate.clone()? as Arc<dyn LspAdapterDelegate>;
let states = local.language_servers.get(server_id)?;
match states {
LanguageServerState::Starting { .. } => None,
LanguageServerState::Running {
adapter, server, ..
- } => Some((
- adapter.adapter.clone(),
- server.clone(),
- delegate.clone()? as Arc<dyn LspAdapterDelegate>,
- )),
+ } => {
+ let fs = fs.clone();
+ let toolchain_store = toolchain_store.clone();
+ let adapter = adapter.clone();
+ let server = server.clone();
+ refreshed_servers.insert(server.name());
+ Some(cx.spawn(async move |_, cx| {
+ let settings =
+ LocalLspStore::workspace_configuration_for_adapter(
+ adapter.adapter.clone(),
+ fs.as_ref(),
+ &delegate,
+ toolchain_store,
+ cx,
+ )
+ .await
+ .ok()?;
+ server
+ .notify::<lsp::notification::DidChangeConfiguration>(
+ &lsp::DidChangeConfigurationParams { settings },
+ )
+ .ok()?;
+ Some(())
+ }))
+ }
}
- })
+ }).collect::<Vec<_>>()
})
.collect::<Vec<_>>()
})
.ok()?;
- let toolchain_store = this.update(cx, |this, cx| this.toolchain_store(cx)).ok()?;
- for (adapter, server, delegate) in servers {
- let settings = LocalLspStore::workspace_configuration_for_adapter(
- adapter,
- fs.as_ref(),
- &delegate,
- toolchain_store.clone(),
- cx,
- )
- .await
- .ok()?;
-
- server
- .notify::<lsp::notification::DidChangeConfiguration>(
- &lsp::DidChangeConfigurationParams { settings },
- )
- .ok();
- }
+ log::info!("Refreshing workspace configurations for servers {refreshed_servers:?}");
+ // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
+ // to stop and unregister its language server wrapper.
+ // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
+ // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
+ let _: Vec<Option<()>> = join_all(servers).await;
Some(())
})
.await;