Skip to content

Commit dfaa095

Browse files
dhruvmanilaAlexWaygood
authored andcommitted
[ty] Add documentation for server traits (#19137)
This PR adds some basic documentation for the traits in the server implementation.
1 parent 3c36648 commit dfaa095

File tree

4 files changed

+123
-38
lines changed

4 files changed

+123
-38
lines changed

crates/ruff_server/src/server/api.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ use self::traits::{NotificationHandler, RequestHandler};
2626

2727
use super::{Result, schedule::BackgroundSchedule};
2828

29-
/// Defines the `document_url` method for implementers of [`traits::Notification`] and [`traits::Request`],
30-
/// given the parameter type used by the implementer.
29+
/// Defines the `document_url` method for implementers of [`Notification`] and [`Request`], given
30+
/// the request or notification parameter type.
31+
///
32+
/// This would only work if the parameter type has a `text_document` field with a `uri` field
33+
/// that is of type [`lsp_types::Url`].
3134
macro_rules! define_document_url {
3235
($params:ident: &$p:ty) => {
3336
fn document_url($params: &$p) -> std::borrow::Cow<lsp_types::Url> {

crates/ruff_server/src/server/api/traits.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
1-
//! A stateful LSP implementation that calls into the Ruff API.
1+
//! Traits for handling requests and notifications from the LSP client.
2+
//!
3+
//! This module defines the trait abstractions used by the language server to handle incoming
4+
//! requests and notifications from clients. It provides a type-safe way to implement LSP handlers
5+
//! with different execution models (synchronous or asynchronous) and automatic retry capabilities.
6+
//!
7+
//! All request and notification handlers must implement the base traits [`RequestHandler`] and
8+
//! [`NotificationHandler`], respectively, which associate them with specific LSP request or
9+
//! notification types. These base traits are then extended by more specific traits that define
10+
//! the execution model of the handler.
11+
//!
12+
//! The [`SyncRequestHandler`] and [`SyncNotificationHandler`] traits are for handlers that
13+
//! executes synchronously on the main loop, providing mutable access to the [`Session`] that
14+
//! contains the current state of the server. This is useful for handlers that need to modify
15+
//! the server state such as when the content of a file changes.
16+
//!
17+
//! The [`BackgroundDocumentRequestHandler`] and [`BackgroundDocumentNotificationHandler`] traits
18+
//! are for handlers that operate on a single document and can be executed on a background thread.
19+
//! These handlers will have access to a snapshot of the document at the time of the request or
20+
//! notification, allowing them to perform operations without blocking the main loop.
21+
//!
22+
//! The [`SyncNotificationHandler`] is the most common trait that would be used because most
23+
//! notifications are specific to a single document and require updating the server state.
24+
//! Similarly, the [`BackgroundDocumentRequestHandler`] is the most common request handler that
25+
//! would be used as most requests are document-specific and can be executed in the background.
26+
//!
27+
//! See the `./requests` and `./notifications` directories for concrete implementations of these
28+
//! traits in action.
229
330
use crate::session::{Client, DocumentSnapshot, Session};
431

@@ -12,9 +39,10 @@ pub(super) trait RequestHandler {
1239
}
1340

1441
/// A request handler that needs mutable access to the session.
15-
/// This will block the main message receiver loop, meaning that no
16-
/// incoming requests or notifications will be handled while `run` is
17-
/// executing. Try to avoid doing any I/O or long-running computations.
42+
///
43+
/// This will block the main message receiver loop, meaning that no incoming requests or
44+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
45+
/// long-running computations.
1846
pub(super) trait SyncRequestHandler: RequestHandler {
1947
fn run(
2048
session: &mut Session,
@@ -24,10 +52,14 @@ pub(super) trait SyncRequestHandler: RequestHandler {
2452
}
2553

2654
/// A request handler that can be run on a background thread.
55+
///
56+
/// This handler is specific to requests that operate on a single document.
2757
pub(super) trait BackgroundDocumentRequestHandler: RequestHandler {
28-
/// `document_url` can be implemented automatically with
29-
/// `define_document_url!(params: &<YourParameterType>)` in the trait
30-
/// implementation.
58+
/// Returns the URL of the document that this request handler operates on.
59+
///
60+
/// This method can be implemented automatically using the [`define_document_url`] macro.
61+
///
62+
/// [`define_document_url`]: super::define_document_url
3163
fn document_url(
3264
params: &<<Self as RequestHandler>::RequestType as Request>::Params,
3365
) -> std::borrow::Cow<lsp_types::Url>;
@@ -47,9 +79,10 @@ pub(super) trait NotificationHandler {
4779
}
4880

4981
/// A notification handler that needs mutable access to the session.
50-
/// This will block the main message receiver loop, meaning that no
51-
/// incoming requests or notifications will be handled while `run` is
52-
/// executing. Try to avoid doing any I/O or long-running computations.
82+
///
83+
/// This will block the main message receiver loop, meaning that no incoming requests or
84+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
85+
/// long-running computations.
5386
pub(super) trait SyncNotificationHandler: NotificationHandler {
5487
fn run(
5588
session: &mut Session,
@@ -60,9 +93,11 @@ pub(super) trait SyncNotificationHandler: NotificationHandler {
6093

6194
/// A notification handler that can be run on a background thread.
6295
pub(super) trait BackgroundDocumentNotificationHandler: NotificationHandler {
63-
/// `document_url` can be implemented automatically with
64-
/// `define_document_url!(params: &<YourParameterType>)` in the trait
65-
/// implementation.
96+
/// Returns the URL of the document that this notification handler operates on.
97+
///
98+
/// This method can be implemented automatically using the [`define_document_url`] macro.
99+
///
100+
/// [`define_document_url`]: super::define_document_url
66101
fn document_url(
67102
params: &<<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
68103
) -> std::borrow::Cow<lsp_types::Url>;

crates/ty_server/src/server/api/requests/diagnostic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::borrow::Cow;
33
use lsp_types::request::DocumentDiagnosticRequest;
44
use lsp_types::{
55
DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportResult,
6-
FullDocumentDiagnosticReport, RelatedFullDocumentDiagnosticReport,
6+
FullDocumentDiagnosticReport, RelatedFullDocumentDiagnosticReport, Url,
77
};
88

99
use crate::server::Result;
@@ -22,7 +22,7 @@ impl RequestHandler for DocumentDiagnosticRequestHandler {
2222
}
2323

2424
impl BackgroundDocumentRequestHandler for DocumentDiagnosticRequestHandler {
25-
fn document_url(params: &DocumentDiagnosticParams) -> Cow<lsp_types::Url> {
25+
fn document_url(params: &DocumentDiagnosticParams) -> Cow<Url> {
2626
Cow::Borrowed(&params.text_document.uri)
2727
}
2828

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,61 @@
1-
//! A stateful LSP implementation that calls into the ty API.
1+
//! Traits for handling requests and notifications from the LSP client.
2+
//!
3+
//! This module defines the trait abstractions used by the language server to handle incoming
4+
//! requests and notifications from clients. It provides a type-safe way to implement LSP handlers
5+
//! with different execution models (synchronous or asynchronous) and automatic retry capabilities.
6+
//!
7+
//! All request and notification handlers must implement the base traits [`RequestHandler`] and
8+
//! [`NotificationHandler`], respectively, which associate them with specific LSP request or
9+
//! notification types. These base traits are then extended by more specific traits that define
10+
//! the execution model of the handler.
11+
//!
12+
//! The [`SyncRequestHandler`] and [`SyncNotificationHandler`] traits are for handlers that
13+
//! executes synchronously on the main loop, providing mutable access to the [`Session`] that
14+
//! contains the current state of the server. This is useful for handlers that need to modify
15+
//! the server state such as when the content of a file changes.
16+
//!
17+
//! The [`BackgroundDocumentRequestHandler`] and [`BackgroundDocumentNotificationHandler`] traits
18+
//! are for handlers that operate on a single document and can be executed on a background thread.
19+
//! These handlers will have access to a snapshot of the document at the time of the request or
20+
//! notification, allowing them to perform operations without blocking the main loop. There is also
21+
//! the [`BackgroundRequestHandler`] trait for handlers that operate on the entire session, which
22+
//! includes all the workspaces, instead of a single document and can also be executed on a
23+
//! background thread like fetching the workspace diagnostics.
24+
//!
25+
//! The [`RetriableRequestHandler`] trait is a marker trait for handlers that can be retried if the
26+
//! Salsa database is modified during execution.
27+
//!
28+
//! The [`SyncNotificationHandler`] is the most common trait that would be used because most
29+
//! notifications are specific to a single document and require updating the server state.
30+
//! Similarly, the [`BackgroundDocumentRequestHandler`] is the most common request handler that
31+
//! would be used as most requests are document-specific and can be executed in the background.
32+
//!
33+
//! See the `./requests` and `./notifications` directories for concrete implementations of these
34+
//! traits in action.
35+
36+
use std::borrow::Cow;
237

338
use std::panic::AssertUnwindSafe;
439

540
use crate::session::client::Client;
641
use crate::session::{DocumentSnapshot, Session, SessionSnapshot};
742

8-
use lsp_types::notification::Notification as LSPNotification;
43+
use lsp_types::Url;
44+
use lsp_types::notification::Notification;
945
use lsp_types::request::Request;
1046
use ty_project::ProjectDatabase;
1147

1248
/// A supertrait for any server request handler.
1349
pub(super) trait RequestHandler {
1450
type RequestType: Request;
15-
const METHOD: &'static str = <<Self as RequestHandler>::RequestType as Request>::METHOD;
51+
const METHOD: &'static str = <<Self as RequestHandler>::RequestType>::METHOD;
1652
}
1753

1854
/// A request handler that needs mutable access to the session.
19-
/// This will block the main message receiver loop, meaning that no
20-
/// incoming requests or notifications will be handled while `run` is
21-
/// executing. Try to avoid doing any I/O or long-running computations.
55+
///
56+
/// This will block the main message receiver loop, meaning that no incoming requests or
57+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
58+
/// long-running computations.
2259
pub(super) trait SyncRequestHandler: RequestHandler {
2360
fn run(
2461
session: &mut Session,
@@ -31,7 +68,13 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
3168
/// Whether this request can be cancelled if the Salsa database is modified.
3269
const RETRY_ON_CANCELLATION: bool = false;
3370

34-
/// The error to return if the request was cancelled due to a modification to the Salsa database.
71+
/// The error to return if the request was cancelled due to a modification to the Salsa
72+
/// database.
73+
///
74+
/// By default, this returns a [`ContentModified`] error to indicate that the content of a
75+
/// document has changed since the request was made.
76+
///
77+
/// [`ContentModified`]: lsp_server::ErrorCode::ContentModified
3578
fn salsa_cancellation_error() -> lsp_server::ResponseError {
3679
lsp_server::ResponseError {
3780
code: lsp_server::ErrorCode::ContentModified as i32,
@@ -45,9 +88,10 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
4588
///
4689
/// This handler is specific to requests that operate on a single document.
4790
pub(super) trait BackgroundDocumentRequestHandler: RetriableRequestHandler {
91+
/// Returns the URL of the document that this request handler operates on.
4892
fn document_url(
4993
params: &<<Self as RequestHandler>::RequestType as Request>::Params,
50-
) -> std::borrow::Cow<lsp_types::Url>;
94+
) -> Cow<Url>;
5195

5296
fn run_with_snapshot(
5397
db: &ProjectDatabase,
@@ -58,6 +102,11 @@ pub(super) trait BackgroundDocumentRequestHandler: RetriableRequestHandler {
58102
}
59103

60104
/// A request handler that can be run on a background thread.
105+
///
106+
/// Unlike [`BackgroundDocumentRequestHandler`], this handler operates on the entire session,
107+
/// which includes all the workspaces, without being tied to a specific document. It is useful for
108+
/// operations that require access to the entire session state, such as fetching workspace
109+
/// diagnostics.
61110
pub(super) trait BackgroundRequestHandler: RetriableRequestHandler {
62111
fn run(
63112
snapshot: AssertUnwindSafe<SessionSnapshot>,
@@ -68,35 +117,33 @@ pub(super) trait BackgroundRequestHandler: RetriableRequestHandler {
68117

69118
/// A supertrait for any server notification handler.
70119
pub(super) trait NotificationHandler {
71-
type NotificationType: LSPNotification;
72-
const METHOD: &'static str =
73-
<<Self as NotificationHandler>::NotificationType as LSPNotification>::METHOD;
120+
type NotificationType: Notification;
121+
const METHOD: &'static str = <<Self as NotificationHandler>::NotificationType>::METHOD;
74122
}
75123

76124
/// A notification handler that needs mutable access to the session.
77-
/// This will block the main message receiver loop, meaning that no
78-
/// incoming requests or notifications will be handled while `run` is
79-
/// executing. Try to avoid doing any I/O or long-running computations.
125+
///
126+
/// This will block the main message receiver loop, meaning that no incoming requests or
127+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
128+
/// long-running computations.
80129
pub(super) trait SyncNotificationHandler: NotificationHandler {
81130
fn run(
82131
session: &mut Session,
83132
client: &Client,
84-
params: <<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
133+
params: <<Self as NotificationHandler>::NotificationType as Notification>::Params,
85134
) -> super::Result<()>;
86135
}
87136

88137
/// A notification handler that can be run on a background thread.
89138
pub(super) trait BackgroundDocumentNotificationHandler: NotificationHandler {
90-
/// `document_url` can be implemented automatically with
91-
/// `define_document_url!(params: &<YourParameterType>)` in the trait
92-
/// implementation.
139+
/// Returns the URL of the document that this notification handler operates on.
93140
fn document_url(
94-
params: &<<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
95-
) -> std::borrow::Cow<lsp_types::Url>;
141+
params: &<<Self as NotificationHandler>::NotificationType as Notification>::Params,
142+
) -> Cow<Url>;
96143

97144
fn run_with_snapshot(
98145
snapshot: DocumentSnapshot,
99146
client: &Client,
100-
params: <<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
147+
params: <<Self as NotificationHandler>::NotificationType as Notification>::Params,
101148
) -> super::Result<()>;
102149
}

0 commit comments

Comments
 (0)