From cc97579c3bb83d0b1f65cfc80d49bfa92452528f Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Thu, 7 Aug 2025 09:58:08 +0530 Subject: [PATCH] [ty] Move server capabilities creation (#19798) --- crates/ty_server/src/capabilities.rs | 80 ++++++++++++++++++++++++++- crates/ty_server/src/server.rs | 82 +--------------------------- 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/crates/ty_server/src/capabilities.rs b/crates/ty_server/src/capabilities.rs index e3bfc054fa..62d87c109c 100644 --- a/crates/ty_server/src/capabilities.rs +++ b/crates/ty_server/src/capabilities.rs @@ -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 { diff --git a/crates/ty_server/src/server.rs b/crates/ty_server/src/server.rs index f172d03016..0ab3f3326c 100644 --- a/crates/ty_server/src/server.rs +++ b/crates/ty_server/src/server.rs @@ -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) + 'static + Sync + Send>;