diff options
Diffstat (limited to 'crates/server/src/main_loop/mod.rs')
-rw-r--r-- | crates/server/src/main_loop/mod.rs | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index 0f66248a5..cd17cab56 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | mod handlers; | 1 | mod handlers; |
2 | mod subscriptions; | ||
2 | 3 | ||
3 | use std::{ | 4 | use std::{ |
4 | collections::{HashSet}, | 5 | collections::{HashSet}, |
@@ -6,7 +7,7 @@ use std::{ | |||
6 | 7 | ||
7 | use threadpool::ThreadPool; | 8 | use threadpool::ThreadPool; |
8 | use crossbeam_channel::{Sender, Receiver}; | 9 | use crossbeam_channel::{Sender, Receiver}; |
9 | use languageserver_types::Url; | 10 | use libanalysis::FileId; |
10 | 11 | ||
11 | use { | 12 | use { |
12 | req, dispatch, | 13 | req, dispatch, |
@@ -14,6 +15,7 @@ use { | |||
14 | io::{Io, RawMsg, RawRequest, RawNotification}, | 15 | io::{Io, RawMsg, RawRequest, RawNotification}, |
15 | vfs::FileEvent, | 16 | vfs::FileEvent, |
16 | server_world::{ServerWorldState, ServerWorld}, | 17 | server_world::{ServerWorldState, ServerWorld}, |
18 | main_loop::subscriptions::{Subscriptions}, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | pub(super) fn main_loop( | 21 | pub(super) fn main_loop( |
@@ -28,6 +30,7 @@ pub(super) fn main_loop( | |||
28 | 30 | ||
29 | let mut pending_requests: HashSet<u64> = HashSet::new(); | 31 | let mut pending_requests: HashSet<u64> = HashSet::new(); |
30 | let mut fs_events_receiver = Some(&fs_events_receiver); | 32 | let mut fs_events_receiver = Some(&fs_events_receiver); |
33 | let mut subs = Subscriptions::new(); | ||
31 | loop { | 34 | loop { |
32 | enum Event { | 35 | enum Event { |
33 | Msg(RawMsg), | 36 | Msg(RawMsg), |
@@ -47,7 +50,7 @@ pub(super) fn main_loop( | |||
47 | None => Event::FsWatcherDead, | 50 | None => Event::FsWatcherDead, |
48 | } | 51 | } |
49 | }; | 52 | }; |
50 | 53 | let mut state_changed = false; | |
51 | match event { | 54 | match event { |
52 | Event::ReceiverDead => { | 55 | Event::ReceiverDead => { |
53 | io.cleanup_receiver()?; | 56 | io.cleanup_receiver()?; |
@@ -70,6 +73,7 @@ pub(super) fn main_loop( | |||
70 | Event::Fs(events) => { | 73 | Event::Fs(events) => { |
71 | trace!("fs change, {} events", events.len()); | 74 | trace!("fs change, {} events", events.len()); |
72 | state.apply_fs_changes(events); | 75 | state.apply_fs_changes(events); |
76 | state_changed = true; | ||
73 | } | 77 | } |
74 | Event::Msg(msg) => { | 78 | Event::Msg(msg) => { |
75 | match msg { | 79 | match msg { |
@@ -79,7 +83,8 @@ pub(super) fn main_loop( | |||
79 | } | 83 | } |
80 | } | 84 | } |
81 | RawMsg::Notification(not) => { | 85 | RawMsg::Notification(not) => { |
82 | on_notification(io, &mut state, pool, &task_sender, not)? | 86 | on_notification(io, &mut state, &mut subs, not)?; |
87 | state_changed = true; | ||
83 | } | 88 | } |
84 | RawMsg::Response(resp) => { | 89 | RawMsg::Response(resp) => { |
85 | if !pending_requests.remove(&resp.id) { | 90 | if !pending_requests.remove(&resp.id) { |
@@ -89,6 +94,15 @@ pub(super) fn main_loop( | |||
89 | } | 94 | } |
90 | } | 95 | } |
91 | }; | 96 | }; |
97 | |||
98 | if state_changed { | ||
99 | update_file_notifications_on_threadpool( | ||
100 | pool, | ||
101 | state.snapshot(), | ||
102 | task_sender.clone(), | ||
103 | subs.subscriptions(), | ||
104 | ) | ||
105 | } | ||
92 | } | 106 | } |
93 | } | 107 | } |
94 | 108 | ||
@@ -140,8 +154,7 @@ fn on_request( | |||
140 | fn on_notification( | 154 | fn on_notification( |
141 | io: &mut Io, | 155 | io: &mut Io, |
142 | state: &mut ServerWorldState, | 156 | state: &mut ServerWorldState, |
143 | pool: &ThreadPool, | 157 | subs: &mut Subscriptions, |
144 | sender: &Sender<Task>, | ||
145 | not: RawNotification, | 158 | not: RawNotification, |
146 | ) -> Result<()> { | 159 | ) -> Result<()> { |
147 | let mut not = Some(not); | 160 | let mut not = Some(not); |
@@ -149,13 +162,8 @@ fn on_notification( | |||
149 | let uri = params.text_document.uri; | 162 | let uri = params.text_document.uri; |
150 | let path = uri.to_file_path() | 163 | let path = uri.to_file_path() |
151 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 164 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
152 | state.add_mem_file(path, params.text_document.text); | 165 | let file_id = state.add_mem_file(path, params.text_document.text); |
153 | update_file_notifications_on_threadpool( | 166 | subs.add_sub(file_id); |
154 | pool, | ||
155 | state.snapshot(), | ||
156 | sender.clone(), | ||
157 | uri, | ||
158 | ); | ||
159 | Ok(()) | 167 | Ok(()) |
160 | })?; | 168 | })?; |
161 | dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| { | 169 | dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| { |
@@ -166,23 +174,15 @@ fn on_notification( | |||
166 | .ok_or_else(|| format_err!("empty changes"))? | 174 | .ok_or_else(|| format_err!("empty changes"))? |
167 | .text; | 175 | .text; |
168 | state.change_mem_file(path.as_path(), text)?; | 176 | state.change_mem_file(path.as_path(), text)?; |
169 | update_file_notifications_on_threadpool( | ||
170 | pool, | ||
171 | state.snapshot(), | ||
172 | sender.clone(), | ||
173 | uri, | ||
174 | ); | ||
175 | Ok(()) | 177 | Ok(()) |
176 | })?; | 178 | })?; |
177 | dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| { | 179 | dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| { |
178 | let uri = params.text_document.uri; | 180 | let uri = params.text_document.uri; |
179 | let path = uri.to_file_path() | 181 | let path = uri.to_file_path() |
180 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 182 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
181 | state.remove_mem_file(path.as_path())?; | 183 | let file_id = state.remove_mem_file(path.as_path())?; |
182 | let not = req::PublishDiagnosticsParams { | 184 | subs.remove_sub(file_id); |
183 | uri, | 185 | let not = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; |
184 | diagnostics: Vec::new(), | ||
185 | }; | ||
186 | let not = dispatch::send_notification::<req::PublishDiagnostics>(not); | 186 | let not = dispatch::send_notification::<req::PublishDiagnostics>(not); |
187 | io.send(RawMsg::Notification(not)); | 187 | io.send(RawMsg::Notification(not)); |
188 | Ok(()) | 188 | Ok(()) |
@@ -227,25 +227,27 @@ fn update_file_notifications_on_threadpool( | |||
227 | pool: &ThreadPool, | 227 | pool: &ThreadPool, |
228 | world: ServerWorld, | 228 | world: ServerWorld, |
229 | sender: Sender<Task>, | 229 | sender: Sender<Task>, |
230 | uri: Url, | 230 | subscriptions: Vec<FileId>, |
231 | ) { | 231 | ) { |
232 | pool.execute(move || { | 232 | pool.execute(move || { |
233 | match handlers::publish_diagnostics(world.clone(), uri.clone()) { | 233 | for file_id in subscriptions { |
234 | Err(e) => { | 234 | match handlers::publish_diagnostics(world.clone(), file_id) { |
235 | error!("failed to compute diagnostics: {:?}", e) | 235 | Err(e) => { |
236 | } | 236 | error!("failed to compute diagnostics: {:?}", e) |
237 | Ok(params) => { | 237 | } |
238 | let not = dispatch::send_notification::<req::PublishDiagnostics>(params); | 238 | Ok(params) => { |
239 | sender.send(Task::Notify(not)); | 239 | let not = dispatch::send_notification::<req::PublishDiagnostics>(params); |
240 | } | 240 | sender.send(Task::Notify(not)); |
241 | } | 241 | } |
242 | match handlers::publish_decorations(world, uri) { | ||
243 | Err(e) => { | ||
244 | error!("failed to compute decorations: {:?}", e) | ||
245 | } | 242 | } |
246 | Ok(params) => { | 243 | match handlers::publish_decorations(world.clone(), file_id) { |
247 | let not = dispatch::send_notification::<req::PublishDecorations>(params); | 244 | Err(e) => { |
248 | sender.send(Task::Notify(not)) | 245 | error!("failed to compute decorations: {:?}", e) |
246 | } | ||
247 | Ok(params) => { | ||
248 | let not = dispatch::send_notification::<req::PublishDecorations>(params); | ||
249 | sender.send(Task::Notify(not)) | ||
250 | } | ||
249 | } | 251 | } |
250 | } | 252 | } |
251 | }); | 253 | }); |