[ty] Move server capabilities creation (#19798)

This commit is contained in:
Dhruv Manilawala 2025-08-07 09:58:08 +05:30 committed by GitHub
parent ef1802b94f
commit cc97579c3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 82 additions and 80 deletions

View file

@ -1,4 +1,14 @@
use lsp_types::{ClientCapabilities, DiagnosticOptions, MarkupKind, WorkDoneProgressOptions};
use lsp_types::{
ClientCapabilities, CompletionOptions, DeclarationCapability, DiagnosticOptions,
DiagnosticServerCapabilities, HoverProviderCapability, InlayHintOptions,
InlayHintServerCapabilities, MarkupKind, OneOf, SelectionRangeProviderCapability,
SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions,
SemanticTokensServerCapabilities, ServerCapabilities, SignatureHelpOptions,
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
TypeDefinitionProviderCapability, WorkDoneProgressOptions,
};
use crate::PositionEncoding;
bitflags::bitflags! {
/// Represents the resolved client capabilities for the language server.
@ -249,6 +259,74 @@ impl ResolvedClientCapabilities {
}
}
pub(crate) fn server_capabilities(
position_encoding: PositionEncoding,
resolved_client_capabilities: ResolvedClientCapabilities,
) -> ServerCapabilities {
let diagnostic_provider =
if resolved_client_capabilities.supports_diagnostic_dynamic_registration() {
// If the client supports dynamic registration, we will register the diagnostic
// capabilities dynamically based on the `ty.diagnosticMode` setting.
None
} else {
// Otherwise, we always advertise support for workspace diagnostics.
Some(DiagnosticServerCapabilities::Options(
server_diagnostic_options(true),
))
};
ServerCapabilities {
position_encoding: Some(position_encoding.into()),
diagnostic_provider,
text_document_sync: Some(TextDocumentSyncCapability::Options(
TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::INCREMENTAL),
..Default::default()
},
)),
type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
definition_provider: Some(OneOf::Left(true)),
declaration_provider: Some(DeclarationCapability::Simple(true)),
references_provider: Some(OneOf::Left(true)),
document_highlight_provider: Some(OneOf::Left(true)),
hover_provider: Some(HoverProviderCapability::Simple(true)),
signature_help_provider: Some(SignatureHelpOptions {
trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
retrigger_characters: Some(vec![")".to_string()]),
work_done_progress_options: WorkDoneProgressOptions::default(),
}),
inlay_hint_provider: Some(OneOf::Right(InlayHintServerCapabilities::Options(
InlayHintOptions::default(),
))),
semantic_tokens_provider: Some(SemanticTokensServerCapabilities::SemanticTokensOptions(
SemanticTokensOptions {
work_done_progress_options: WorkDoneProgressOptions::default(),
legend: SemanticTokensLegend {
token_types: ty_ide::SemanticTokenType::all()
.iter()
.map(|token_type| token_type.as_lsp_concept().into())
.collect(),
token_modifiers: ty_ide::SemanticTokenModifier::all_names()
.iter()
.map(|&s| s.into())
.collect(),
},
range: Some(true),
full: Some(SemanticTokensFullOptions::Bool(true)),
},
)),
completion_provider: Some(CompletionOptions {
trigger_characters: Some(vec!['.'.to_string()]),
..Default::default()
}),
selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
document_symbol_provider: Some(OneOf::Left(true)),
workspace_symbol_provider: Some(OneOf::Left(true)),
..Default::default()
}
}
/// Creates the default [`DiagnosticOptions`] for the server.
pub(crate) fn server_diagnostic_options(workspace_diagnostics: bool) -> DiagnosticOptions {
DiagnosticOptions {

View file

@ -2,18 +2,11 @@
use self::schedule::spawn_main_loop;
use crate::PositionEncoding;
use crate::capabilities::{ResolvedClientCapabilities, server_diagnostic_options};
use crate::capabilities::{ResolvedClientCapabilities, server_capabilities};
use crate::session::{InitializationOptions, Session};
use anyhow::Context;
use lsp_server::Connection;
use lsp_types::{
ClientCapabilities, DeclarationCapability, DiagnosticServerCapabilities,
HoverProviderCapability, InitializeParams, InlayHintOptions, InlayHintServerCapabilities,
MessageType, SelectionRangeProviderCapability, SemanticTokensLegend, SemanticTokensOptions,
SemanticTokensServerCapabilities, ServerCapabilities, SignatureHelpOptions,
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
TypeDefinitionProviderCapability, Url, WorkDoneProgressOptions,
};
use lsp_types::{ClientCapabilities, InitializeParams, MessageType, Url};
use ruff_db::system::System;
use std::num::NonZeroUsize;
use std::panic::{PanicHookInfo, RefUnwindSafe};
@ -77,7 +70,7 @@ impl Server {
let resolved_client_capabilities = ResolvedClientCapabilities::new(&client_capabilities);
let position_encoding = Self::find_best_position_encoding(&client_capabilities);
let server_capabilities =
Self::server_capabilities(position_encoding, resolved_client_capabilities);
server_capabilities(position_encoding, resolved_client_capabilities);
let version = ruff_db::program_version().unwrap_or("Unknown");
tracing::debug!("Version: {version}");
@ -210,75 +203,6 @@ impl Server {
})
.unwrap_or_default()
}
// TODO: Move this to `capabilities.rs`?
fn server_capabilities(
position_encoding: PositionEncoding,
resolved_client_capabilities: ResolvedClientCapabilities,
) -> ServerCapabilities {
let diagnostic_provider =
if resolved_client_capabilities.supports_diagnostic_dynamic_registration() {
// If the client supports dynamic registration, we will register the diagnostic
// capabilities dynamically based on the `ty.diagnosticMode` setting.
None
} else {
// Otherwise, we always advertise support for workspace diagnostics.
Some(DiagnosticServerCapabilities::Options(
server_diagnostic_options(true),
))
};
ServerCapabilities {
position_encoding: Some(position_encoding.into()),
diagnostic_provider,
text_document_sync: Some(TextDocumentSyncCapability::Options(
TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::INCREMENTAL),
..Default::default()
},
)),
type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
definition_provider: Some(lsp_types::OneOf::Left(true)),
declaration_provider: Some(DeclarationCapability::Simple(true)),
references_provider: Some(lsp_types::OneOf::Left(true)),
document_highlight_provider: Some(lsp_types::OneOf::Left(true)),
hover_provider: Some(HoverProviderCapability::Simple(true)),
signature_help_provider: Some(SignatureHelpOptions {
trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
retrigger_characters: Some(vec![")".to_string()]),
work_done_progress_options: lsp_types::WorkDoneProgressOptions::default(),
}),
inlay_hint_provider: Some(lsp_types::OneOf::Right(
InlayHintServerCapabilities::Options(InlayHintOptions::default()),
)),
semantic_tokens_provider: Some(
SemanticTokensServerCapabilities::SemanticTokensOptions(SemanticTokensOptions {
work_done_progress_options: WorkDoneProgressOptions::default(),
legend: SemanticTokensLegend {
token_types: ty_ide::SemanticTokenType::all()
.iter()
.map(|token_type| token_type.as_lsp_concept().into())
.collect(),
token_modifiers: ty_ide::SemanticTokenModifier::all_names()
.iter()
.map(|&s| s.into())
.collect(),
},
range: Some(true),
full: Some(lsp_types::SemanticTokensFullOptions::Bool(true)),
}),
),
completion_provider: Some(lsp_types::CompletionOptions {
trigger_characters: Some(vec!['.'.to_string()]),
..Default::default()
}),
selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
document_symbol_provider: Some(lsp_types::OneOf::Left(true)),
workspace_symbol_provider: Some(lsp_types::OneOf::Left(true)),
..Default::default()
}
}
}
type PanicHook = Box<dyn Fn(&PanicHookInfo<'_>) + 'static + Sync + Send>;