@@ -15,25 +15,39 @@ use solar_interface::{
1515use solar_sema:: Compiler ;
1616use tokio:: task:: JoinHandle ;
1717
18- use crate :: { NotifyResult , config:: negotiate_capabilities, proto, vfs:: Vfs } ;
18+ use crate :: {
19+ NotifyResult ,
20+ config:: { Config , negotiate_capabilities} ,
21+ proto,
22+ vfs:: Vfs ,
23+ } ;
1924
2025pub ( crate ) struct GlobalState {
2126 client : ClientSocket ,
2227 pub ( crate ) vfs : Arc < RwLock < Vfs > > ,
28+ pub ( crate ) config : Arc < Config > ,
2329 analysis_version : usize ,
2430}
2531
2632impl GlobalState {
2733 pub ( crate ) fn new ( client : ClientSocket ) -> Self {
28- Self { client, vfs : Arc :: new ( Default :: default ( ) ) , analysis_version : 0 }
34+ Self {
35+ client,
36+ vfs : Arc :: new ( Default :: default ( ) ) ,
37+ analysis_version : 0 ,
38+ config : Arc :: new ( Default :: default ( ) ) ,
39+ }
2940 }
3041
3142 pub ( crate ) fn on_initialize (
3243 & mut self ,
3344 params : InitializeParams ,
3445 ) -> impl Future < Output = Result < InitializeResult , ResponseError > > + use < > {
35- let ( capabilities, _config) = negotiate_capabilities ( params) ;
46+ let ( capabilities, mut config) = negotiate_capabilities ( params) ;
47+
48+ config. rediscover_workspaces ( ) ;
3649
50+ self . config = Arc :: new ( config) ;
3751 std:: future:: ready ( Ok ( InitializeResult {
3852 capabilities,
3953 server_info : Some ( ServerInfo {
@@ -98,16 +112,36 @@ impl GlobalState {
98112 let _ = compiler. lower_asts ( ) ;
99113 let _ = compiler. analysis ( ) ;
100114
101- // todo handle diagnostic clearing
102115 // todo clean this mess up boya
103- let diagnostics: HashMap < _ , Vec < _ > > = diag_buffer
116+ let mut diagnostics: HashMap < lsp_types:: Url , Vec < lsp_types:: Diagnostic > > =
117+ HashMap :: new ( ) ;
118+ for ( path, diagnostic) in diag_buffer
104119 . read ( )
105120 . iter ( )
106121 . filter_map ( |diag| proto:: diagnostic ( compiler. sess ( ) . source_map ( ) , diag) )
107- . fold ( HashMap :: new ( ) , |mut diags, ( path, diag) | {
108- diags. entry ( path) . or_default ( ) . push ( diag) ;
109- diags
110- } ) ;
122+ {
123+ diagnostics. entry ( path) . or_default ( ) . push ( diagnostic) ;
124+ }
125+
126+ // For any other file that was parsed, we additionally load it into the VFS for
127+ // later, and set an empty diagnostics set. This is to clear the existing
128+ // diagnostics for files that went from an errored to an ok state, but tracking this
129+ // separately is more efficient given most of these are wasted allocations.
130+ for url in compiler
131+ . gcx ( )
132+ . sources
133+ . sources
134+ . iter ( )
135+ . filter_map ( |source| source. file . name . as_real ( ) )
136+ . filter_map ( |path| lsp_types:: Url :: from_file_path ( path) . ok ( ) )
137+ {
138+ // todo: all of this can be a `HashMap::try_insert` (<https://github.com/rust-lang/rust/issues/82766>)
139+ if diagnostics. contains_key ( & url) {
140+ continue ;
141+ }
142+ diagnostics. insert ( url, Vec :: new ( ) ) ;
143+ }
144+
111145 for ( uri, diagnostics) in diagnostics. into_iter ( ) {
112146 let _ = snapshot. client . publish_diagnostics ( PublishDiagnosticsParams :: new (
113147 uri,
@@ -122,7 +156,11 @@ impl GlobalState {
122156 }
123157
124158 fn snapshot ( & self ) -> GlobalStateSnapshot {
125- GlobalStateSnapshot { client : self . client . clone ( ) , vfs : self . vfs . clone ( ) }
159+ GlobalStateSnapshot {
160+ client : self . client . clone ( ) ,
161+ vfs : self . vfs . clone ( ) ,
162+ config : self . config . clone ( ) ,
163+ }
126164 }
127165
128166 fn spawn_with_snapshot < T : Send + ' static > (
@@ -137,4 +175,5 @@ impl GlobalState {
137175pub ( crate ) struct GlobalStateSnapshot {
138176 client : ClientSocket ,
139177 vfs : Arc < RwLock < Vfs > > ,
178+ config : Arc < Config > ,
140179}
0 commit comments