11use std:: path:: { Path , PathBuf } ;
2- use std:: str:: FromStr ;
32use std:: sync:: Arc ;
43
54use ignore:: gitignore:: Gitignore ;
@@ -22,6 +21,7 @@ use crate::linter::{
2221 tsgo_linter:: TsgoLinter ,
2322} ;
2423use crate :: utils:: normalize_path;
24+ use crate :: worker:: WorkerDiagnostics ;
2525use crate :: { ConcurrentHashMap , LINT_CONFIG_FILE } ;
2626
2727use super :: config_walker:: ConfigWalker ;
@@ -39,52 +39,9 @@ pub struct ServerLinter {
3939 ignore_matcher : LintIgnoreMatcher ,
4040 gitignore_glob : Vec < Gitignore > ,
4141 lint_on_run : Run ,
42- diagnostics : ServerLinterDiagnostics ,
4342 extended_paths : FxHashSet < PathBuf > ,
4443}
4544
46- #[ derive( Debug , Default ) ]
47- struct ServerLinterDiagnostics {
48- isolated_linter : Arc < ConcurrentHashMap < String , Option < Vec < DiagnosticReport > > > > ,
49- tsgo_linter : Arc < ConcurrentHashMap < String , Option < Vec < DiagnosticReport > > > > ,
50- }
51-
52- impl ServerLinterDiagnostics {
53- pub fn get_diagnostics ( & self , path : & str ) -> Option < Vec < DiagnosticReport > > {
54- let mut reports = Vec :: new ( ) ;
55- let mut found = false ;
56- if let Some ( entry) = self . isolated_linter . pin ( ) . get ( path) {
57- found = true ;
58- if let Some ( diagnostics) = entry {
59- reports. extend ( diagnostics. clone ( ) ) ;
60- }
61- }
62- if let Some ( entry) = self . tsgo_linter . pin ( ) . get ( path) {
63- found = true ;
64- if let Some ( diagnostics) = entry {
65- reports. extend ( diagnostics. clone ( ) ) ;
66- }
67- }
68- if found { Some ( reports) } else { None }
69- }
70-
71- pub fn remove_diagnostics ( & self , path : & str ) {
72- self . isolated_linter . pin ( ) . remove ( path) ;
73- self . tsgo_linter . pin ( ) . remove ( path) ;
74- }
75-
76- pub fn get_cached_files_of_diagnostics ( & self ) -> Vec < String > {
77- let isolated_files = self . isolated_linter . pin ( ) . keys ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
78- let tsgo_files = self . tsgo_linter . pin ( ) . keys ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
79-
80- let mut files = Vec :: with_capacity ( isolated_files. len ( ) + tsgo_files. len ( ) ) ;
81- files. extend ( isolated_files) ;
82- files. extend ( tsgo_files) ;
83- files. dedup ( ) ;
84- files
85- }
86- }
87-
8845impl ServerLinter {
8946 pub fn new ( root_uri : & Uri , options : & LSPLintOptions ) -> Self {
9047 let root_path = root_uri. to_file_path ( ) . unwrap ( ) ;
@@ -174,7 +131,6 @@ impl ServerLinter {
174131 gitignore_glob : Self :: create_ignore_glob ( & root_path) ,
175132 extended_paths,
176133 lint_on_run : options. run ,
177- diagnostics : ServerLinterDiagnostics :: default ( ) ,
178134 tsgo_linter : if options. type_aware {
179135 Arc :: new ( Some ( TsgoLinter :: new ( & root_path, config_store) ) )
180136 } else {
@@ -267,27 +223,15 @@ impl ServerLinter {
267223 gitignore_globs
268224 }
269225
270- pub fn remove_diagnostics ( & self , uri : & Uri ) {
271- self . diagnostics . remove_diagnostics ( & uri. to_string ( ) ) ;
272- }
273-
274- pub fn get_cached_diagnostics ( & self , uri : & Uri ) -> Option < Vec < DiagnosticReport > > {
275- self . diagnostics . get_diagnostics ( & uri. to_string ( ) )
276- }
277-
278- pub fn get_cached_files_of_diagnostics ( & self ) -> Vec < Uri > {
279- self . diagnostics
280- . get_cached_files_of_diagnostics ( )
281- . into_iter ( )
282- . filter_map ( |s| Uri :: from_str ( & s) . ok ( ) )
283- . collect ( )
284- }
285-
286- pub async fn revalidate_diagnostics ( & self , uris : Vec < Uri > ) -> Vec < ( String , Vec < Diagnostic > ) > {
226+ pub async fn revalidate_diagnostics (
227+ & self ,
228+ uris : Vec < Uri > ,
229+ diagnostics_map : & WorkerDiagnostics ,
230+ ) -> Vec < ( String , Vec < Diagnostic > ) > {
287231 let mut diagnostics = Vec :: with_capacity ( uris. len ( ) ) ;
288232 for uri in uris {
289233 if let Some ( file_diagnostic) =
290- self . run_single ( & uri, None , ServerLinterRun :: Always ) . await
234+ self . run_single ( & uri, None , ServerLinterRun :: Always , diagnostics_map ) . await
291235 {
292236 diagnostics. push ( (
293237 uri. to_string ( ) ,
@@ -325,6 +269,7 @@ impl ServerLinter {
325269 uri : & Uri ,
326270 content : Option < String > ,
327271 run_type : ServerLinterRun ,
272+ diagnostics_map : & WorkerDiagnostics ,
328273 ) -> Option < Vec < DiagnosticReport > > {
329274 let ( oxlint, tsgolint) = match ( run_type, self . lint_on_run ) {
330275 // run everything on save, or when it is forced
@@ -356,17 +301,17 @@ impl ServerLinter {
356301 let mut isolated_linter = self . isolated_linter . lock ( ) . await ;
357302 isolated_linter. run_single ( uri, content. clone ( ) )
358303 } ;
359- self . diagnostics . isolated_linter . pin ( ) . insert ( uri. to_string ( ) , diagnostics) ;
304+ diagnostics_map . isolated_linter . pin ( ) . insert ( uri. to_string ( ) , diagnostics) ;
360305 }
361306
362307 if tsgolint && let Some ( tsgo_linter) = self . tsgo_linter . as_ref ( ) {
363- self . diagnostics
308+ diagnostics_map
364309 . tsgo_linter
365310 . pin ( )
366311 . insert ( uri. to_string ( ) , tsgo_linter. lint_file ( uri, content. clone ( ) ) ) ;
367312 }
368313
369- self . diagnostics . get_diagnostics ( & uri. to_string ( ) )
314+ diagnostics_map . get_diagnostics ( & uri. to_string ( ) )
370315 }
371316
372317 pub fn needs_restart ( old_options : & LSPLintOptions , new_options : & LSPLintOptions ) -> bool {
@@ -423,11 +368,9 @@ mod test {
423368 use std:: path:: { Path , PathBuf } ;
424369
425370 use crate :: {
426- ConcurrentHashMap ,
427371 linter:: {
428- error_with_position:: DiagnosticReport ,
429372 options:: { LintOptions , Run , UnusedDisableDirectives } ,
430- server_linter:: { ServerLinter , ServerLinterDiagnostics } ,
373+ server_linter:: ServerLinter ,
431374 } ,
432375 tester:: { Tester , get_file_path} ,
433376 } ;
@@ -467,45 +410,6 @@ mod test {
467410 assert ! ( configs_dirs[ 0 ] . ends_with( "init_nested_configs" ) ) ;
468411 }
469412
470- #[ test]
471- fn test_get_diagnostics_found_and_none_entries ( ) {
472- let key = "file:///test.js" . to_string ( ) ;
473-
474- // Case 1: Both entries present, Some diagnostics
475- let diag = DiagnosticReport :: default ( ) ;
476- let diag_map = ConcurrentHashMap :: default ( ) ;
477- diag_map. pin ( ) . insert ( key. clone ( ) , Some ( vec ! [ diag. clone( ) ] ) ) ;
478- let tsgo_map = ConcurrentHashMap :: default ( ) ;
479- tsgo_map. pin ( ) . insert ( key. clone ( ) , Some ( vec ! [ diag] ) ) ;
480-
481- let server_diag = super :: ServerLinterDiagnostics {
482- isolated_linter : std:: sync:: Arc :: new ( diag_map) ,
483- tsgo_linter : std:: sync:: Arc :: new ( tsgo_map) ,
484- } ;
485- let result = server_diag. get_diagnostics ( & key) ;
486- assert ! ( result. is_some( ) ) ;
487- assert_eq ! ( result. unwrap( ) . len( ) , 2 ) ;
488-
489- // Case 2: Entry present, but value is None
490- let diag_map_none = ConcurrentHashMap :: default ( ) ;
491- diag_map_none. pin ( ) . insert ( key. clone ( ) , None ) ;
492- let tsgo_map_none = ConcurrentHashMap :: default ( ) ;
493- tsgo_map_none. pin ( ) . insert ( key. clone ( ) , None ) ;
494-
495- let server_diag_none = ServerLinterDiagnostics {
496- isolated_linter : std:: sync:: Arc :: new ( diag_map_none) ,
497- tsgo_linter : std:: sync:: Arc :: new ( tsgo_map_none) ,
498- } ;
499- let result_none = server_diag_none. get_diagnostics ( & key) ;
500- assert ! ( result_none. is_some( ) ) ;
501- assert_eq ! ( result_none. unwrap( ) . len( ) , 0 ) ;
502-
503- // Case 3: No entry at all
504- let server_diag_empty = ServerLinterDiagnostics :: default ( ) ;
505- let result_empty = server_diag_empty. get_diagnostics ( & key) ;
506- assert ! ( result_empty. is_none( ) ) ;
507- }
508-
509413 #[ test]
510414 #[ cfg( not( target_endian = "big" ) ) ]
511415 fn test_lint_on_run_on_type_on_type ( ) {
0 commit comments