@@ -15,13 +15,13 @@ use lsp_types as lsp;
15
15
use parking_lot:: Mutex ;
16
16
use serde:: Deserialize ;
17
17
use serde_json:: Value ;
18
- use std:: future:: Future ;
19
- use std:: process:: Stdio ;
20
18
use std:: sync:: {
21
19
atomic:: { AtomicU64 , Ordering } ,
22
20
Arc ,
23
21
} ;
24
22
use std:: { collections:: HashMap , path:: PathBuf } ;
23
+ use std:: { future:: Future , sync:: atomic:: AtomicBool } ;
24
+ use std:: { process:: Stdio , sync:: atomic} ;
25
25
use tokio:: {
26
26
io:: { BufReader , BufWriter } ,
27
27
process:: { Child , Command } ,
@@ -57,6 +57,9 @@ pub struct Client {
57
57
initialize_notify : Arc < Notify > ,
58
58
/// workspace folders added while the server is still initializing
59
59
req_timeout : u64 ,
60
+ // there is no server capability to know if server supports it
61
+ // set to true on first PublishDiagnostic notification
62
+ supports_publish_diagnostic : AtomicBool ,
60
63
}
61
64
62
65
impl Client {
@@ -238,6 +241,7 @@ impl Client {
238
241
root_uri,
239
242
workspace_folders : Mutex :: new ( workspace_folders) ,
240
243
initialize_notify : initialize_notify. clone ( ) ,
244
+ supports_publish_diagnostic : AtomicBool :: new ( false ) ,
241
245
} ;
242
246
243
247
Ok ( ( client, server_rx, initialize_notify) )
@@ -277,6 +281,17 @@ impl Client {
277
281
. expect ( "language server not yet initialized!" )
278
282
}
279
283
284
+ pub fn set_publish_diagnostic ( & self , val : bool ) {
285
+ self . supports_publish_diagnostic
286
+ . fetch_or ( val, atomic:: Ordering :: Relaxed ) ;
287
+ }
288
+
289
+ /// Whether the server supports Publish Diagnostic
290
+ pub fn publish_diagnostic ( & self ) -> bool {
291
+ self . supports_publish_diagnostic
292
+ . load ( atomic:: Ordering :: Relaxed )
293
+ }
294
+
280
295
/// Client has to be initialized otherwise this function panics
281
296
#[ inline]
282
297
pub fn supports_feature ( & self , feature : LanguageServerFeature ) -> bool {
@@ -346,7 +361,12 @@ impl Client {
346
361
capabilities. workspace_symbol_provider,
347
362
Some ( OneOf :: Left ( true ) | OneOf :: Right ( _) )
348
363
) ,
349
- LanguageServerFeature :: Diagnostics => true , // there's no extra server capability
364
+ LanguageServerFeature :: Diagnostics => {
365
+ self . publish_diagnostic ( ) || matches ! ( capabilities. diagnostic_provider, Some ( _) )
366
+ }
367
+ LanguageServerFeature :: PullDiagnostics => {
368
+ matches ! ( capabilities. diagnostic_provider, Some ( _) )
369
+ }
350
370
LanguageServerFeature :: RenameSymbol => matches ! (
351
371
capabilities. rename_provider,
352
372
Some ( OneOf :: Left ( true ) ) | Some ( OneOf :: Right ( _) )
@@ -630,6 +650,10 @@ impl Client {
630
650
dynamic_registration : Some ( false ) ,
631
651
resolve_support : None ,
632
652
} ) ,
653
+ diagnostic : Some ( lsp:: DiagnosticClientCapabilities {
654
+ dynamic_registration : Some ( false ) ,
655
+ related_document_support : Some ( true ) ,
656
+ } ) ,
633
657
..Default :: default ( )
634
658
} ) ,
635
659
window : Some ( lsp:: WindowClientCapabilities {
@@ -1141,6 +1165,32 @@ impl Client {
1141
1165
} )
1142
1166
}
1143
1167
1168
+ pub fn text_document_diagnostic (
1169
+ & self ,
1170
+ text_document : lsp:: TextDocumentIdentifier ,
1171
+ previous_result_id : Option < String > ,
1172
+ ) -> Option < impl Future < Output = Result < Value > > > {
1173
+ let capabilities = self . capabilities . get ( ) . unwrap ( ) ;
1174
+
1175
+ // Return early if the server does not support pull diagnostic.
1176
+ let identifier = match capabilities. diagnostic_provider . as_ref ( ) ? {
1177
+ lsp:: DiagnosticServerCapabilities :: Options ( cap) => cap. identifier . clone ( ) ,
1178
+ lsp:: DiagnosticServerCapabilities :: RegistrationOptions ( cap) => {
1179
+ cap. diagnostic_options . identifier . clone ( )
1180
+ }
1181
+ } ;
1182
+
1183
+ let params = lsp:: DocumentDiagnosticParams {
1184
+ text_document,
1185
+ identifier,
1186
+ previous_result_id,
1187
+ work_done_progress_params : lsp:: WorkDoneProgressParams :: default ( ) ,
1188
+ partial_result_params : lsp:: PartialResultParams :: default ( ) ,
1189
+ } ;
1190
+
1191
+ Some ( self . call :: < lsp:: request:: DocumentDiagnosticRequest > ( params) )
1192
+ }
1193
+
1144
1194
pub fn text_document_document_highlight (
1145
1195
& self ,
1146
1196
text_document : lsp:: TextDocumentIdentifier ,
0 commit comments