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 ;
2
37
3
38
use std:: panic:: AssertUnwindSafe ;
4
39
5
40
use crate :: session:: client:: Client ;
6
41
use crate :: session:: { DocumentSnapshot , Session , SessionSnapshot } ;
7
42
8
- use lsp_types:: notification:: Notification as LSPNotification ;
43
+ use lsp_types:: Url ;
44
+ use lsp_types:: notification:: Notification ;
9
45
use lsp_types:: request:: Request ;
10
46
use ty_project:: ProjectDatabase ;
11
47
12
48
/// A supertrait for any server request handler.
13
49
pub ( super ) trait RequestHandler {
14
50
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 ;
16
52
}
17
53
18
54
/// 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.
22
59
pub ( super ) trait SyncRequestHandler : RequestHandler {
23
60
fn run (
24
61
session : & mut Session ,
@@ -31,7 +68,13 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
31
68
/// Whether this request can be cancelled if the Salsa database is modified.
32
69
const RETRY_ON_CANCELLATION : bool = false ;
33
70
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
35
78
fn salsa_cancellation_error ( ) -> lsp_server:: ResponseError {
36
79
lsp_server:: ResponseError {
37
80
code : lsp_server:: ErrorCode :: ContentModified as i32 ,
@@ -45,9 +88,10 @@ pub(super) trait RetriableRequestHandler: RequestHandler {
45
88
///
46
89
/// This handler is specific to requests that operate on a single document.
47
90
pub ( super ) trait BackgroundDocumentRequestHandler : RetriableRequestHandler {
91
+ /// Returns the URL of the document that this request handler operates on.
48
92
fn document_url (
49
93
params : & <<Self as RequestHandler >:: RequestType as Request >:: Params ,
50
- ) -> std :: borrow :: Cow < lsp_types :: Url > ;
94
+ ) -> Cow < Url > ;
51
95
52
96
fn run_with_snapshot (
53
97
db : & ProjectDatabase ,
@@ -58,6 +102,11 @@ pub(super) trait BackgroundDocumentRequestHandler: RetriableRequestHandler {
58
102
}
59
103
60
104
/// 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.
61
110
pub ( super ) trait BackgroundRequestHandler : RetriableRequestHandler {
62
111
fn run (
63
112
snapshot : AssertUnwindSafe < SessionSnapshot > ,
@@ -68,35 +117,33 @@ pub(super) trait BackgroundRequestHandler: RetriableRequestHandler {
68
117
69
118
/// A supertrait for any server notification handler.
70
119
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 ;
74
122
}
75
123
76
124
/// 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.
80
129
pub ( super ) trait SyncNotificationHandler : NotificationHandler {
81
130
fn run (
82
131
session : & mut Session ,
83
132
client : & Client ,
84
- params : <<Self as NotificationHandler >:: NotificationType as LSPNotification >:: Params ,
133
+ params : <<Self as NotificationHandler >:: NotificationType as Notification >:: Params ,
85
134
) -> super :: Result < ( ) > ;
86
135
}
87
136
88
137
/// A notification handler that can be run on a background thread.
89
138
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.
93
140
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 > ;
96
143
97
144
fn run_with_snapshot (
98
145
snapshot : DocumentSnapshot ,
99
146
client : & Client ,
100
- params : <<Self as NotificationHandler >:: NotificationType as LSPNotification >:: Params ,
147
+ params : <<Self as NotificationHandler >:: NotificationType as Notification >:: Params ,
101
148
) -> super :: Result < ( ) > ;
102
149
}
0 commit comments