aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_proc_macro/src/process.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_proc_macro/src/process.rs')
-rw-r--r--crates/ra_proc_macro/src/process.rs118
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..5bcdacb48 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
9use io::{BufRead, BufReader}; 9use io::{BufRead, BufReader};
10use std::{ 10use 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
31struct Task {
32 req: Request,
33 result_tx: Sender<Option<Response>>,
34}
35
36struct Process {
37 path: PathBuf,
38 child: Child,
39}
40
41impl Drop for Process {
42 fn drop(&mut self) {
43 let _ = self.child.kill();
44 }
45}
46
47impl 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
82impl ProcMacroProcessSrv { 31impl 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
145struct Task {
146 req: Request,
147 result_tx: Sender<Option<Response>>,
148}
149
150struct Process {
151 path: PathBuf,
152 args: Vec<OsString>,
153 child: Child,
154}
155
156impl Drop for Process {
157 fn drop(&mut self) {
158 let _ = self.child.kill();
159 }
160}
161
162impl 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
187fn 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::inherit())
193 .spawn()
194}
195
200fn send_request( 196fn 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}