diff options
Diffstat (limited to 'crates/ra_proc_macro/src/process.rs')
-rw-r--r-- | crates/ra_proc_macro/src/process.rs | 118 |
1 files changed, 57 insertions, 61 deletions
diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs index f851570bc..673f80a7a 100644 --- a/crates/ra_proc_macro/src/process.rs +++ b/crates/ra_proc_macro/src/process.rs | |||
@@ -9,7 +9,7 @@ use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTas | |||
9 | use io::{BufRead, BufReader}; | 9 | use io::{BufRead, BufReader}; |
10 | use std::{ | 10 | use std::{ |
11 | convert::{TryFrom, TryInto}, | 11 | convert::{TryFrom, TryInto}, |
12 | ffi::OsStr, | 12 | ffi::{OsStr, OsString}, |
13 | io::{self, Write}, | 13 | io::{self, Write}, |
14 | path::{Path, PathBuf}, | 14 | path::{Path, PathBuf}, |
15 | process::{Child, Command, Stdio}, | 15 | process::{Child, Command, Stdio}, |
@@ -28,66 +28,11 @@ pub(crate) struct ProcMacroProcessThread { | |||
28 | handle: jod_thread::JoinHandle<()>, | 28 | handle: jod_thread::JoinHandle<()>, |
29 | } | 29 | } |
30 | 30 | ||
31 | struct Task { | ||
32 | req: Request, | ||
33 | result_tx: Sender<Option<Response>>, | ||
34 | } | ||
35 | |||
36 | struct Process { | ||
37 | path: PathBuf, | ||
38 | child: Child, | ||
39 | } | ||
40 | |||
41 | impl Drop for Process { | ||
42 | fn drop(&mut self) { | ||
43 | let _ = self.child.kill(); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | impl Process { | ||
48 | fn run<I, S>(process_path: &Path, args: I) -> Result<Process, io::Error> | ||
49 | where | ||
50 | I: IntoIterator<Item = S>, | ||
51 | S: AsRef<OsStr>, | ||
52 | { | ||
53 | let child = Command::new(process_path.clone()) | ||
54 | .args(args) | ||
55 | .stdin(Stdio::piped()) | ||
56 | .stdout(Stdio::piped()) | ||
57 | .stderr(Stdio::null()) | ||
58 | .spawn()?; | ||
59 | |||
60 | Ok(Process { path: process_path.into(), child }) | ||
61 | } | ||
62 | |||
63 | fn restart(&mut self) -> Result<(), io::Error> { | ||
64 | let _ = self.child.kill(); | ||
65 | self.child = Command::new(self.path.clone()) | ||
66 | .stdin(Stdio::piped()) | ||
67 | .stdout(Stdio::piped()) | ||
68 | .stderr(Stdio::null()) | ||
69 | .spawn()?; | ||
70 | Ok(()) | ||
71 | } | ||
72 | |||
73 | fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> { | ||
74 | let stdin = self.child.stdin.take()?; | ||
75 | let stdout = self.child.stdout.take()?; | ||
76 | let read = BufReader::new(stdout); | ||
77 | |||
78 | Some((stdin, read)) | ||
79 | } | ||
80 | } | ||
81 | |||
82 | impl ProcMacroProcessSrv { | 31 | impl ProcMacroProcessSrv { |
83 | pub fn run<I, S>( | 32 | pub fn run( |
84 | process_path: &Path, | 33 | process_path: PathBuf, |
85 | args: I, | 34 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, |
86 | ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error> | 35 | ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> { |
87 | where | ||
88 | I: IntoIterator<Item = S>, | ||
89 | S: AsRef<OsStr>, | ||
90 | { | ||
91 | let process = Process::run(process_path, args)?; | 36 | let process = Process::run(process_path, args)?; |
92 | 37 | ||
93 | let (task_tx, task_rx) = bounded(0); | 38 | let (task_tx, task_rx) = bounded(0); |
@@ -197,11 +142,62 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) { | |||
197 | } | 142 | } |
198 | } | 143 | } |
199 | 144 | ||
145 | struct Task { | ||
146 | req: Request, | ||
147 | result_tx: Sender<Option<Response>>, | ||
148 | } | ||
149 | |||
150 | struct Process { | ||
151 | path: PathBuf, | ||
152 | args: Vec<OsString>, | ||
153 | child: Child, | ||
154 | } | ||
155 | |||
156 | impl Drop for Process { | ||
157 | fn drop(&mut self) { | ||
158 | let _ = self.child.kill(); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | impl Process { | ||
163 | fn run( | ||
164 | path: PathBuf, | ||
165 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | ||
166 | ) -> io::Result<Process> { | ||
167 | let args = args.into_iter().map(|s| s.as_ref().into()).collect(); | ||
168 | let child = mk_child(&path, &args)?; | ||
169 | Ok(Process { path, args, child }) | ||
170 | } | ||
171 | |||
172 | fn restart(&mut self) -> io::Result<()> { | ||
173 | let _ = self.child.kill(); | ||
174 | self.child = mk_child(&self.path, &self.args)?; | ||
175 | Ok(()) | ||
176 | } | ||
177 | |||
178 | fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> { | ||
179 | let stdin = self.child.stdin.take()?; | ||
180 | let stdout = self.child.stdout.take()?; | ||
181 | let read = BufReader::new(stdout); | ||
182 | |||
183 | Some((stdin, read)) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | fn mk_child(path: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> io::Result<Child> { | ||
188 | Command::new(&path) | ||
189 | .args(args) | ||
190 | .stdin(Stdio::piped()) | ||
191 | .stdout(Stdio::piped()) | ||
192 | .stderr(Stdio::null()) | ||
193 | .spawn() | ||
194 | } | ||
195 | |||
200 | fn send_request( | 196 | fn send_request( |
201 | mut writer: &mut impl Write, | 197 | mut writer: &mut impl Write, |
202 | mut reader: &mut impl BufRead, | 198 | mut reader: &mut impl BufRead, |
203 | req: Request, | 199 | req: Request, |
204 | ) -> Result<Option<Response>, io::Error> { | 200 | ) -> io::Result<Option<Response>> { |
205 | req.write(&mut writer)?; | 201 | req.write(&mut writer)?; |
206 | Ok(Response::read(&mut reader)?) | 202 | Ok(Response::read(&mut reader)?) |
207 | } | 203 | } |