Ignore capability registrations with empty capabilities (#36000)
This commit is contained in:
parent
b35e69692d
commit
481e3e5092
1 changed files with 133 additions and 135 deletions
|
@ -3367,20 +3367,6 @@ impl LocalLspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
|
||||||
reg: lsp::Registration,
|
|
||||||
) -> anyhow::Result<OneOf<bool, T>> {
|
|
||||||
let caps = match reg
|
|
||||||
.register_options
|
|
||||||
.map(|options| serde_json::from_value::<T>(options))
|
|
||||||
.transpose()?
|
|
||||||
{
|
|
||||||
None => OneOf::Left(true),
|
|
||||||
Some(options) => OneOf::Right(options),
|
|
||||||
};
|
|
||||||
Ok(caps)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
|
fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
|
||||||
if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
|
if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
|
||||||
cx.emit(LspStoreEvent::LanguageServerUpdate {
|
cx.emit(LspStoreEvent::LanguageServerUpdate {
|
||||||
|
@ -11690,18 +11676,16 @@ impl LspStore {
|
||||||
// Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
|
// Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
|
||||||
}
|
}
|
||||||
"workspace/symbol" => {
|
"workspace/symbol" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.workspace_symbol_provider = Some(options);
|
capabilities.workspace_symbol_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"workspace/fileOperations" => {
|
"workspace/fileOperations" => {
|
||||||
let caps = reg
|
if let Some(options) = reg.register_options {
|
||||||
.register_options
|
let caps = serde_json::from_value(options)?;
|
||||||
.map(serde_json::from_value)
|
|
||||||
.transpose()?
|
|
||||||
.unwrap_or_default();
|
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities
|
capabilities
|
||||||
.workspace
|
.workspace
|
||||||
|
@ -11710,171 +11694,173 @@ impl LspStore {
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"workspace/executeCommand" => {
|
"workspace/executeCommand" => {
|
||||||
let options = reg
|
if let Some(options) = reg.register_options {
|
||||||
.register_options
|
let options = serde_json::from_value(options)?;
|
||||||
.map(serde_json::from_value)
|
|
||||||
.transpose()?
|
|
||||||
.unwrap_or_default();
|
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.execute_command_provider = Some(options);
|
capabilities.execute_command_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/rangeFormatting" => {
|
"textDocument/rangeFormatting" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_range_formatting_provider = Some(options);
|
capabilities.document_range_formatting_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/onTypeFormatting" => {
|
"textDocument/onTypeFormatting" => {
|
||||||
let options = reg
|
if let Some(options) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_default();
|
{
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_on_type_formatting_provider = Some(options);
|
capabilities.document_on_type_formatting_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/formatting" => {
|
"textDocument/formatting" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_formatting_provider = Some(options);
|
capabilities.document_formatting_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/rename" => {
|
"textDocument/rename" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.rename_provider = Some(options);
|
capabilities.rename_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/inlayHint" => {
|
"textDocument/inlayHint" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.inlay_hint_provider = Some(options);
|
capabilities.inlay_hint_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/documentSymbol" => {
|
"textDocument/documentSymbol" => {
|
||||||
let options = parse_register_capabilities(reg)?;
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_symbol_provider = Some(options);
|
capabilities.document_symbol_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/codeAction" => {
|
"textDocument/codeAction" => {
|
||||||
let options = reg
|
if let Some(options) = reg
|
||||||
.register_options
|
|
||||||
.map(serde_json::from_value)
|
|
||||||
.transpose()?;
|
|
||||||
let provider_capability = match options {
|
|
||||||
None => lsp::CodeActionProviderCapability::Simple(true),
|
|
||||||
Some(options) => lsp::CodeActionProviderCapability::Options(options),
|
|
||||||
};
|
|
||||||
server.update_capabilities(|capabilities| {
|
|
||||||
capabilities.code_action_provider = Some(provider_capability);
|
|
||||||
});
|
|
||||||
notify_server_capabilities_updated(&server, cx);
|
|
||||||
}
|
|
||||||
"textDocument/definition" => {
|
|
||||||
let caps = parse_register_capabilities(reg)?;
|
|
||||||
server.update_capabilities(|capabilities| {
|
|
||||||
capabilities.definition_provider = Some(caps);
|
|
||||||
});
|
|
||||||
notify_server_capabilities_updated(&server, cx);
|
|
||||||
}
|
|
||||||
"textDocument/completion" => {
|
|
||||||
let caps = reg
|
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_default();
|
{
|
||||||
|
server.update_capabilities(|capabilities| {
|
||||||
|
capabilities.code_action_provider =
|
||||||
|
Some(lsp::CodeActionProviderCapability::Options(options));
|
||||||
|
});
|
||||||
|
notify_server_capabilities_updated(&server, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"textDocument/definition" => {
|
||||||
|
if let Some(options) = parse_register_capabilities(reg)? {
|
||||||
|
server.update_capabilities(|capabilities| {
|
||||||
|
capabilities.definition_provider = Some(options);
|
||||||
|
});
|
||||||
|
notify_server_capabilities_updated(&server, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"textDocument/completion" => {
|
||||||
|
if let Some(caps) = reg
|
||||||
|
.register_options
|
||||||
|
.map(serde_json::from_value)
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.completion_provider = Some(caps);
|
capabilities.completion_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/hover" => {
|
"textDocument/hover" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| lsp::HoverProviderCapability::Simple(true));
|
{
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.hover_provider = Some(caps);
|
capabilities.hover_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/signatureHelp" => {
|
"textDocument/signatureHelp" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_default();
|
{
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.signature_help_provider = Some(caps);
|
capabilities.signature_help_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/synchronization" => {
|
"textDocument/synchronization" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| {
|
{
|
||||||
lsp::TextDocumentSyncCapability::Options(
|
|
||||||
lsp::TextDocumentSyncOptions::default(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.text_document_sync = Some(caps);
|
capabilities.text_document_sync = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/codeLens" => {
|
"textDocument/codeLens" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| lsp::CodeLensOptions {
|
{
|
||||||
resolve_provider: None,
|
|
||||||
});
|
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.code_lens_provider = Some(caps);
|
capabilities.code_lens_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/diagnostic" => {
|
"textDocument/diagnostic" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| {
|
{
|
||||||
lsp::DiagnosticServerCapabilities::RegistrationOptions(
|
|
||||||
lsp::DiagnosticRegistrationOptions::default(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.diagnostic_provider = Some(caps);
|
capabilities.diagnostic_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"textDocument/colorProvider" => {
|
"textDocument/colorProvider" => {
|
||||||
let caps = reg
|
if let Some(caps) = reg
|
||||||
.register_options
|
.register_options
|
||||||
.map(serde_json::from_value)
|
.map(serde_json::from_value)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| lsp::ColorProviderCapability::Simple(true));
|
{
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.color_provider = Some(caps);
|
capabilities.color_provider = Some(caps);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_ => log::warn!("unhandled capability registration: {reg:?}"),
|
_ => log::warn!("unhandled capability registration: {reg:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12016,6 +12002,18 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Registration with empty capabilities should be ignored.
|
||||||
|
// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/formatting.ts#L67-L70
|
||||||
|
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
||||||
|
reg: lsp::Registration,
|
||||||
|
) -> anyhow::Result<Option<OneOf<bool, T>>> {
|
||||||
|
Ok(reg
|
||||||
|
.register_options
|
||||||
|
.map(|options| serde_json::from_value::<T>(options))
|
||||||
|
.transpose()?
|
||||||
|
.map(OneOf::Right))
|
||||||
|
}
|
||||||
|
|
||||||
fn subscribe_to_binary_statuses(
|
fn subscribe_to_binary_statuses(
|
||||||
languages: &Arc<LanguageRegistry>,
|
languages: &Arc<LanguageRegistry>,
|
||||||
cx: &mut Context<'_, LspStore>,
|
cx: &mut Context<'_, LspStore>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue