diff options
Diffstat (limited to 'crates/server/src/main.rs')
-rw-r--r-- | crates/server/src/main.rs | 104 |
1 files changed, 6 insertions, 98 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index eeb343b80..3e3bd44a1 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs | |||
@@ -17,26 +17,20 @@ extern crate walkdir; | |||
17 | extern crate libeditor; | 17 | extern crate libeditor; |
18 | extern crate libanalysis; | 18 | extern crate libanalysis; |
19 | extern crate libsyntax2; | 19 | extern crate libsyntax2; |
20 | extern crate gen_lsp_server; | ||
20 | extern crate im; | 21 | extern crate im; |
21 | extern crate relative_path; | 22 | extern crate relative_path; |
22 | 23 | ||
23 | mod io; | ||
24 | mod caps; | 24 | mod caps; |
25 | mod req; | 25 | mod req; |
26 | mod dispatch; | ||
27 | mod conv; | 26 | mod conv; |
28 | mod main_loop; | 27 | mod main_loop; |
29 | mod vfs; | 28 | mod vfs; |
30 | mod path_map; | 29 | mod path_map; |
31 | mod server_world; | 30 | mod server_world; |
32 | 31 | ||
33 | use threadpool::ThreadPool; | ||
34 | use crossbeam_channel::bounded; | ||
35 | use flexi_logger::{Logger, Duplicate}; | 32 | use flexi_logger::{Logger, Duplicate}; |
36 | 33 | use gen_lsp_server::{run_server, stdio_transport}; | |
37 | use ::{ | ||
38 | io::{Io, RawMsg, RawResponse, RawNotification}, | ||
39 | }; | ||
40 | 34 | ||
41 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 35 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
42 | 36 | ||
@@ -60,96 +54,10 @@ fn main() -> Result<()> { | |||
60 | } | 54 | } |
61 | 55 | ||
62 | fn main_inner() -> Result<()> { | 56 | fn main_inner() -> Result<()> { |
63 | let mut io = Io::from_stdio(); | 57 | let (receiver, sender, threads) = stdio_transport(); |
64 | let res = initialize(&mut io); | 58 | run_server(caps::server_capabilities(), main_loop::main_loop, receiver, sender)?; |
65 | info!("shutting down IO..."); | 59 | info!("shutting down IO..."); |
66 | let io_res = io.stop(); | 60 | threads.join()?; |
67 | info!("... IO is down"); | 61 | info!("... IO is down"); |
68 | match (res, io_res) { | 62 | Ok(()) |
69 | (Ok(()), Ok(())) => Ok(()), | ||
70 | (res, Ok(())) => res, | ||
71 | (Ok(()), io_res) => io_res, | ||
72 | (res, Err(io_err)) => { | ||
73 | error!("shutdown error: {:?}", io_err); | ||
74 | res | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | fn initialize(io: &mut Io) -> Result<()> { | ||
80 | match io.recv()? { | ||
81 | RawMsg::Notification(n) => | ||
82 | bail!("expected initialize request, got {:?}", n), | ||
83 | RawMsg::Response(res) => | ||
84 | bail!("expected initialize request, got {:?}", res), | ||
85 | |||
86 | RawMsg::Request(req) => { | ||
87 | let req = dispatch::handle_request::<req::Initialize, _>(req, |_params, resp| { | ||
88 | let res = req::InitializeResult { capabilities: caps::server_capabilities() }; | ||
89 | let resp = resp.into_response(Ok(res))?; | ||
90 | io.send(RawMsg::Response(resp)); | ||
91 | Ok(()) | ||
92 | })?; | ||
93 | if let Err(req) = req { | ||
94 | bail!("expected initialize request, got {:?}", req) | ||
95 | } | ||
96 | match io.recv()? { | ||
97 | RawMsg::Notification(n) => { | ||
98 | if n.method != "initialized" { | ||
99 | bail!("expected initialized notification"); | ||
100 | } | ||
101 | } | ||
102 | _ => bail!("expected initialized notification"), | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | initialized(io) | ||
107 | } | ||
108 | |||
109 | enum Task { | ||
110 | Respond(RawResponse), | ||
111 | Notify(RawNotification), | ||
112 | Die(::failure::Error), | ||
113 | } | ||
114 | |||
115 | fn initialized(io: &mut Io) -> Result<()> { | ||
116 | { | ||
117 | let mut pool = ThreadPool::new(4); | ||
118 | let (task_sender, task_receiver) = bounded::<Task>(16); | ||
119 | let (fs_events_receiver, watcher) = vfs::watch(vec![ | ||
120 | ::std::env::current_dir()?, | ||
121 | ]); | ||
122 | info!("lifecycle: handshake finished, server ready to serve requests"); | ||
123 | let res = main_loop::main_loop( | ||
124 | io, | ||
125 | &mut pool, | ||
126 | task_sender, | ||
127 | task_receiver.clone(), | ||
128 | fs_events_receiver, | ||
129 | ); | ||
130 | |||
131 | info!("waiting for background jobs to finish..."); | ||
132 | task_receiver.for_each(drop); | ||
133 | pool.join(); | ||
134 | info!("...background jobs have finished"); | ||
135 | |||
136 | info!("waiting for file watcher to finish..."); | ||
137 | watcher.stop()?; | ||
138 | info!("...file watcher has finished"); | ||
139 | |||
140 | res | ||
141 | }?; | ||
142 | |||
143 | match io.recv()? { | ||
144 | RawMsg::Notification(n) => { | ||
145 | if n.method == "exit" { | ||
146 | info!("lifecycle: shutdown complete"); | ||
147 | return Ok(()); | ||
148 | } | ||
149 | bail!("unexpected notification during shutdown: {:?}", n) | ||
150 | } | ||
151 | m => { | ||
152 | bail!("unexpected message during shutdown: {:?}", m) | ||
153 | } | ||
154 | } | ||
155 | } | 63 | } |