1
1
//! The main loop of `rust-analyzer` responsible for dispatching LSP
2
2
//! requests/replies and notifications back to the client.
3
+ use crate :: lsp:: ext;
3
4
use std:: {
4
5
fmt,
5
6
time:: { Duration , Instant } ,
@@ -56,10 +57,16 @@ pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> {
56
57
enum Event {
57
58
Lsp ( lsp_server:: Message ) ,
58
59
Task ( Task ) ,
60
+ QueuedTask ( QueuedTask ) ,
59
61
Vfs ( vfs:: loader:: Message ) ,
60
62
Flycheck ( flycheck:: Message ) ,
61
63
}
62
64
65
+ #[ derive( Debug ) ]
66
+ pub ( crate ) enum QueuedTask {
67
+ CheckIfIndexed ( lsp_types:: Url ) ,
68
+ }
69
+
63
70
#[ derive( Debug ) ]
64
71
pub ( crate ) enum Task {
65
72
Response ( lsp_server:: Response ) ,
@@ -104,6 +111,7 @@ impl fmt::Debug for Event {
104
111
match self {
105
112
Event :: Lsp ( it) => fmt:: Debug :: fmt ( it, f) ,
106
113
Event :: Task ( it) => fmt:: Debug :: fmt ( it, f) ,
114
+ Event :: QueuedTask ( it) => fmt:: Debug :: fmt ( it, f) ,
107
115
Event :: Vfs ( it) => fmt:: Debug :: fmt ( it, f) ,
108
116
Event :: Flycheck ( it) => fmt:: Debug :: fmt ( it, f) ,
109
117
}
@@ -182,6 +190,9 @@ impl GlobalState {
182
190
recv( self . task_pool. receiver) -> task =>
183
191
Some ( Event :: Task ( task. unwrap( ) ) ) ,
184
192
193
+ recv( self . task_queue. receiver) -> task =>
194
+ Some ( Event :: QueuedTask ( task. unwrap( ) ) ) ,
195
+
185
196
recv( self . fmt_pool. receiver) -> task =>
186
197
Some ( Event :: Task ( task. unwrap( ) ) ) ,
187
198
@@ -199,7 +210,7 @@ impl GlobalState {
199
210
let _p = profile:: span ( "GlobalState::handle_event" ) ;
200
211
201
212
let event_dbg_msg = format ! ( "{event:?}" ) ;
202
- tracing:: debug!( "{:?} handle_event({})" , loop_start , event_dbg_msg ) ;
213
+ tracing:: debug!( ?loop_start , ?event , "handle_event" ) ;
203
214
if tracing:: enabled!( tracing:: Level :: INFO ) {
204
215
let task_queue_len = self . task_pool . handle . len ( ) ;
205
216
if task_queue_len > 0 {
@@ -214,6 +225,10 @@ impl GlobalState {
214
225
lsp_server:: Message :: Notification ( not) => self . on_notification ( not) ?,
215
226
lsp_server:: Message :: Response ( resp) => self . complete_request ( resp) ,
216
227
} ,
228
+ Event :: QueuedTask ( task) => {
229
+ let _p = profile:: span ( "GlobalState::handle_event/queued_task" ) ;
230
+ self . handle_queued_task ( task) ;
231
+ }
217
232
Event :: Task ( task) => {
218
233
let _p = profile:: span ( "GlobalState::handle_event/task" ) ;
219
234
let mut prime_caches_progress = Vec :: new ( ) ;
@@ -607,6 +622,34 @@ impl GlobalState {
607
622
}
608
623
}
609
624
625
+ fn handle_queued_task ( & mut self , task : QueuedTask ) {
626
+ match task {
627
+ QueuedTask :: CheckIfIndexed ( uri) => {
628
+ let snap = self . snapshot ( ) ;
629
+ let sender = self . sender . clone ( ) ;
630
+
631
+ self . task_pool . handle . spawn_with_sender ( ThreadIntent :: Worker , move |_| {
632
+ tracing:: debug!( ?uri, "handling uri" ) ;
633
+ let id = from_proto:: file_id ( & snap, & uri) . expect ( "unable to get FileId" ) ;
634
+ if let Ok ( crates) = & snap. analysis . crates_for ( id) {
635
+ if crates. is_empty ( ) {
636
+ let not = lsp_server:: Notification :: new (
637
+ ext:: UnindexedProject :: METHOD . to_string ( ) ,
638
+ ext:: UnindexedProjectParams {
639
+ text_documents : vec ! [ lsp_types:: TextDocumentIdentifier { uri } ] ,
640
+ } ,
641
+ ) ;
642
+ sender. send ( not. into ( ) ) . expect ( "unable to send notification" ) ;
643
+ tracing:: debug!( "sent notification" ) ;
644
+ } else {
645
+ tracing:: debug!( ?uri, "is indexed" ) ;
646
+ }
647
+ }
648
+ } ) ;
649
+ }
650
+ }
651
+ }
652
+
610
653
fn handle_flycheck_msg ( & mut self , message : flycheck:: Message ) {
611
654
match message {
612
655
flycheck:: Message :: AddDiagnostic { id, workspace_root, diagnostic } => {
0 commit comments