@@ -86,7 +86,7 @@ impl FileDiagnostic {
8686 }
8787
8888 /// 清除指定文件的诊断信息
89- pub fn clear_file_diagnostics ( & self , uri : lsp_types:: Uri ) {
89+ pub fn clear_push_file_diagnostics ( & self , uri : lsp_types:: Uri ) {
9090 let diagnostic_param = lsp_types:: PublishDiagnosticsParams {
9191 uri,
9292 diagnostics : vec ! [ ] ,
@@ -112,7 +112,7 @@ impl FileDiagnostic {
112112 tokio:: spawn ( async move {
113113 tokio:: select! {
114114 _ = tokio:: time:: sleep( Duration :: from_millis( interval) ) => {
115- workspace_diagnostic ( analysis, client_proxy, status_bar, silent, cancel_token) . await
115+ push_workspace_diagnostic ( analysis, client_proxy, status_bar, silent, cancel_token) . await
116116 }
117117 _ = cancel_token. cancelled( ) => {
118118 log:: info!( "cancel workspace diagnostic" ) ;
@@ -130,6 +130,15 @@ impl FileDiagnostic {
130130 tokens. clear ( ) ;
131131 }
132132
133+ pub async fn cancel_workspace_diagnostic ( & self ) {
134+ let mut token = self . workspace_diagnostic_token . lock ( ) . await ;
135+ if let Some ( token) = token. as_ref ( ) {
136+ token. cancel ( ) ;
137+ debug ! ( "cancel workspace diagnostic" ) ;
138+ }
139+ token. take ( ) ;
140+ }
141+
133142 pub async fn pull_file_diagnostics (
134143 & self ,
135144 uri : Uri ,
@@ -140,14 +149,137 @@ impl FileDiagnostic {
140149 return vec ! [ ] ;
141150 } ;
142151
143- self . clear_file_diagnostics ( uri) ;
144-
145152 let diagnostics = analysis. diagnose_file ( file_id, cancel_token) ;
146153 diagnostics. unwrap_or_default ( )
147154 }
155+
156+ pub async fn pull_workspace_diagnostics_slow (
157+ & self ,
158+ cancel_token : CancellationToken ,
159+ ) -> Vec < ( Uri , Vec < Diagnostic > ) > {
160+ let mut token = self . workspace_diagnostic_token . lock ( ) . await ;
161+ if let Some ( token) = token. as_ref ( ) {
162+ token. cancel ( ) ;
163+ debug ! ( "cancel workspace diagnostic" ) ;
164+ }
165+ token. replace ( cancel_token. clone ( ) ) ;
166+ drop ( token) ;
167+
168+ let mut result = Vec :: new ( ) ;
169+ let analysis = self . analysis . read ( ) . await ;
170+ let main_workspace_file_ids = analysis
171+ . compilation
172+ . get_db ( )
173+ . get_module_index ( )
174+ . get_main_workspace_file_ids ( ) ;
175+ drop ( analysis) ;
176+
177+ for file_id in main_workspace_file_ids {
178+ if cancel_token. is_cancelled ( ) {
179+ break ;
180+ }
181+ let analysis = self . analysis . read ( ) . await ;
182+ if let Some ( uri) = analysis. get_uri ( file_id) {
183+ let diagnostics = analysis. diagnose_file ( file_id, cancel_token. clone ( ) ) ;
184+ if let Some ( diagnostics) = diagnostics {
185+ result. push ( ( uri, diagnostics) ) ;
186+ }
187+ }
188+ }
189+
190+ result
191+ }
192+
193+ pub async fn pull_workspace_diagnostics_fast (
194+ & self ,
195+ cancel_token : CancellationToken ,
196+ ) -> Vec < ( Uri , Vec < Diagnostic > ) > {
197+ let mut token = self . workspace_diagnostic_token . lock ( ) . await ;
198+ if let Some ( token) = token. as_ref ( ) {
199+ token. cancel ( ) ;
200+ debug ! ( "cancel workspace diagnostic" ) ;
201+ }
202+ token. replace ( cancel_token. clone ( ) ) ;
203+ drop ( token) ;
204+
205+ let mut result = Vec :: new ( ) ;
206+ let analysis = self . analysis . read ( ) . await ;
207+ let main_workspace_file_ids = analysis
208+ . compilation
209+ . get_db ( )
210+ . get_module_index ( )
211+ . get_main_workspace_file_ids ( ) ;
212+ drop ( analysis) ;
213+
214+ let status_bar = self . status_bar . clone ( ) ;
215+ status_bar
216+ . create_progress_task ( ProgressTask :: DiagnoseWorkspace )
217+ . await ;
218+
219+ let ( tx, mut rx) = tokio:: sync:: mpsc:: channel :: < Option < ( Vec < Diagnostic > , Uri ) > > ( 100 ) ;
220+ let valid_file_count = main_workspace_file_ids. len ( ) ;
221+ if valid_file_count == 0 {
222+ return result;
223+ }
224+
225+ let analysis = self . analysis . clone ( ) ;
226+ for file_id in main_workspace_file_ids {
227+ let analysis = analysis. clone ( ) ;
228+ let token = cancel_token. clone ( ) ;
229+ let tx = tx. clone ( ) ;
230+ tokio:: spawn ( async move {
231+ let analysis = analysis. read ( ) . await ;
232+ let diagnostics = analysis. diagnose_file ( file_id, token) ;
233+ if let Some ( diagnostics) = diagnostics {
234+ let uri = analysis. get_uri ( file_id) . unwrap ( ) ;
235+ let _ = tx. send ( Some ( ( diagnostics, uri) ) ) . await ;
236+ } else {
237+ let _ = tx. send ( None ) . await ;
238+ }
239+ } ) ;
240+ }
241+
242+ let mut count = 0 ;
243+ if valid_file_count != 0 {
244+ let text = format ! ( "diagnose {} files" , valid_file_count) ;
245+ let _p = Profile :: new ( text. as_str ( ) ) ;
246+ let mut last_percentage = 0 ;
247+ while let Some ( file_diagnostic_result) = rx. recv ( ) . await {
248+ if cancel_token. is_cancelled ( ) {
249+ break ;
250+ }
251+
252+ if let Some ( ( diagnostics, uri) ) = file_diagnostic_result {
253+ result. push ( ( uri, diagnostics) ) ;
254+ }
255+
256+ count += 1 ;
257+ let percentage_done = ( ( count as f32 / valid_file_count as f32 ) * 100.0 ) as u32 ;
258+ if last_percentage != percentage_done {
259+ last_percentage = percentage_done;
260+ let message = format ! ( "diagnostic {}%" , percentage_done) ;
261+ status_bar. update_progress_task (
262+ ProgressTask :: DiagnoseWorkspace ,
263+ Some ( percentage_done) ,
264+ Some ( message) ,
265+ ) ;
266+ }
267+ if count == valid_file_count {
268+ break ;
269+ }
270+ }
271+ }
272+
273+ status_bar. finish_progress_task (
274+ ProgressTask :: DiagnoseWorkspace ,
275+ Some ( "Diagnosis complete" . to_string ( ) ) ,
276+ ) ;
277+
278+ result
279+ }
148280}
149281
150- async fn workspace_diagnostic (
282+ async fn push_workspace_diagnostic (
151283 analysis : Arc < RwLock < EmmyLuaAnalysis > > ,
152284 client_proxy : Arc < ClientProxy > ,
153285 status_bar : Arc < StatusBar > ,
@@ -217,13 +349,16 @@ async fn workspace_diagnostic(
217349 ) ;
218350 }
219351 if count == valid_file_count {
220- status_bar. finish_progress_task (
221- ProgressTask :: DiagnoseWorkspace ,
222- Some ( "Diagnosis complete" . to_string ( ) ) ,
223- ) ;
224352 break ;
225353 }
226354 }
227355 }
228356 }
357+
358+ if !silent {
359+ status_bar. finish_progress_task (
360+ ProgressTask :: DiagnoseWorkspace ,
361+ Some ( "Diagnosis complete" . to_string ( ) ) ,
362+ ) ;
363+ }
229364}
0 commit comments