Skip to content

Commit 97b0b39

Browse files
committed
[ty] Add documentation for server traits
1 parent 3be83d3 commit 97b0b39

File tree

2 files changed

+69
-23
lines changed

2 files changed

+69
-23
lines changed

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: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,59 @@
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 workspace
22+
//! instead of a single document and can also be executed on a background thread like fetching the
23+
//! 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 crate::session::client::Client;
439
use crate::session::{DocumentSnapshot, Session, WorkspaceSnapshot};
540

6-
use lsp_types::notification::Notification as LSPNotification;
41+
use lsp_types::Url;
42+
use lsp_types::notification::Notification;
743
use lsp_types::request::Request;
844
use ty_project::ProjectDatabase;
945

1046
/// A supertrait for any server request handler.
1147
pub(super) trait RequestHandler {
1248
type RequestType: Request;
13-
const METHOD: &'static str = <<Self as RequestHandler>::RequestType as Request>::METHOD;
49+
const METHOD: &'static str = <<Self as RequestHandler>::RequestType>::METHOD;
1450
}
1551

1652
/// A request handler that needs mutable access to the session.
17-
/// This will block the main message receiver loop, meaning that no
18-
/// incoming requests or notifications will be handled while `run` is
19-
/// executing. Try to avoid doing any I/O or long-running computations.
53+
///
54+
/// This will block the main message receiver loop, meaning that no incoming requests or
55+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
56+
/// long-running computations.
2057
pub(super) trait SyncRequestHandler: RequestHandler {
2158
fn run(
2259
session: &mut Session,
@@ -29,7 +66,13 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
2966
/// Whether this request can be cancelled if the Salsa database is modified.
3067
const RETRY_ON_CANCELLATION: bool = false;
3168

32-
/// The error to return if the request was cancelled due to a modification to the Salsa database.
69+
/// The error to return if the request was cancelled due to a modification to the Salsa
70+
/// database.
71+
///
72+
/// By default, this returns a [`ContentModified`] error to indicate that the content of a
73+
/// document has changed since the request was made.
74+
///
75+
/// [`ContentModified`]: lsp_server::ErrorCode::ContentModified
3376
fn salsa_cancellation_error() -> lsp_server::ResponseError {
3477
lsp_server::ResponseError {
3578
code: lsp_server::ErrorCode::ContentModified as i32,
@@ -43,9 +86,10 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
4386
///
4487
/// This handler is specific to requests that operate on a single document.
4588
pub(super) trait BackgroundDocumentRequestHandler: RetriableRequestHandler {
89+
/// Returns the URL of the document that this request handler operates on.
4690
fn document_url(
4791
params: &<<Self as RequestHandler>::RequestType as Request>::Params,
48-
) -> std::borrow::Cow<lsp_types::Url>;
92+
) -> Cow<Url>;
4993

5094
fn run_with_snapshot(
5195
db: &ProjectDatabase,
@@ -56,6 +100,10 @@ pub(super) trait BackgroundDocumentRequestHandler: RetriableRequestHandler {
56100
}
57101

58102
/// A request handler that can be run on a background thread.
103+
///
104+
/// Unlike [`BackgroundDocumentRequestHandler`], this handler operates on the entire workspace
105+
/// without being tied to a specific document. It is useful for operations that require access to
106+
/// the entire workspace state, such as fetching workspace diagnostics.
59107
pub(super) trait BackgroundRequestHandler: RetriableRequestHandler {
60108
fn run(
61109
snapshot: WorkspaceSnapshot,
@@ -66,35 +114,33 @@ pub(super) trait BackgroundRequestHandler: RetriableRequestHandler {
66114

67115
/// A supertrait for any server notification handler.
68116
pub(super) trait NotificationHandler {
69-
type NotificationType: LSPNotification;
70-
const METHOD: &'static str =
71-
<<Self as NotificationHandler>::NotificationType as LSPNotification>::METHOD;
117+
type NotificationType: Notification;
118+
const METHOD: &'static str = <<Self as NotificationHandler>::NotificationType>::METHOD;
72119
}
73120

74121
/// A notification handler that needs mutable access to the session.
75-
/// This will block the main message receiver loop, meaning that no
76-
/// incoming requests or notifications will be handled while `run` is
77-
/// executing. Try to avoid doing any I/O or long-running computations.
122+
///
123+
/// This will block the main message receiver loop, meaning that no incoming requests or
124+
/// notifications will be handled while `run` is executing. Try to avoid doing any I/O or
125+
/// long-running computations.
78126
pub(super) trait SyncNotificationHandler: NotificationHandler {
79127
fn run(
80128
session: &mut Session,
81129
client: &Client,
82-
params: <<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
130+
params: <<Self as NotificationHandler>::NotificationType as Notification>::Params,
83131
) -> super::Result<()>;
84132
}
85133

86134
/// A notification handler that can be run on a background thread.
87135
pub(super) trait BackgroundDocumentNotificationHandler: NotificationHandler {
88-
/// `document_url` can be implemented automatically with
89-
/// `define_document_url!(params: &<YourParameterType>)` in the trait
90-
/// implementation.
136+
/// Returns the URL of the document that this notification handler operates on.
91137
fn document_url(
92-
params: &<<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
93-
) -> std::borrow::Cow<lsp_types::Url>;
138+
params: &<<Self as NotificationHandler>::NotificationType as Notification>::Params,
139+
) -> Cow<Url>;
94140

95141
fn run_with_snapshot(
96142
snapshot: DocumentSnapshot,
97143
client: &Client,
98-
params: <<Self as NotificationHandler>::NotificationType as LSPNotification>::Params,
144+
params: <<Self as NotificationHandler>::NotificationType as Notification>::Params,
99145
) -> super::Result<()>;
100146
}

0 commit comments

Comments
 (0)