From 177becea98bddcd995a2abec59c6b60bac6b5a2b Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 16 Apr 2020 21:13:57 +0800 Subject: Add proc-macro cli command for rust-analyzer --- crates/ra_proc_macro/src/lib.rs | 7 +++- crates/ra_proc_macro/src/process.rs | 8 ++-- crates/ra_proc_macro_srv/src/cli.rs | 56 ++++++++++++++++++++++++++ crates/ra_proc_macro_srv/src/lib.rs | 6 ++- crates/ra_proc_macro_srv/src/main.rs | 55 ------------------------- crates/rust-analyzer/Cargo.toml | 2 +- crates/rust-analyzer/src/bin/args.rs | 2 + crates/rust-analyzer/src/bin/main.rs | 6 +++ crates/rust-analyzer/src/cli/load_cargo.rs | 5 ++- crates/rust-analyzer/src/config.rs | 8 +++- crates/rust-analyzer/src/world.rs | 6 +-- crates/rust-analyzer/tests/heavy_tests/main.rs | 6 ++- 12 files changed, 96 insertions(+), 71 deletions(-) create mode 100644 crates/ra_proc_macro_srv/src/cli.rs delete mode 100644 crates/ra_proc_macro_srv/src/main.rs (limited to 'crates') diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs index 63da9f1b4..14a675db2 100644 --- a/crates/ra_proc_macro/src/lib.rs +++ b/crates/ra_proc_macro/src/lib.rs @@ -56,8 +56,11 @@ pub struct ProcMacroClient { } impl ProcMacroClient { - pub fn extern_process(process_path: &Path) -> Result { - let (thread, process) = ProcMacroProcessSrv::run(process_path)?; + pub fn extern_process>( + process_path: &Path, + args: &[T], + ) -> Result { + let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?; Ok(ProcMacroClient { kind: ProcMacroClientKind::Process { process: Arc::new(process), thread }, }) diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs index e8c85be38..b5e8493ac 100644 --- a/crates/ra_proc_macro/src/process.rs +++ b/crates/ra_proc_macro/src/process.rs @@ -44,8 +44,9 @@ impl Drop for Process { } impl Process { - fn run(process_path: &Path) -> Result { + fn run>(process_path: &Path, args: &[T]) -> Result { let child = Command::new(process_path.clone()) + .args(args.iter().map(|it| it.as_ref())) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::null()) @@ -74,10 +75,11 @@ impl Process { } impl ProcMacroProcessSrv { - pub fn run( + pub fn run>( process_path: &Path, + args: &[T], ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error> { - let process = Process::run(process_path)?; + let process = Process::run(process_path, args)?; let (task_tx, task_rx) = bounded(0); let handle = jod_thread::spawn(move || { diff --git a/crates/ra_proc_macro_srv/src/cli.rs b/crates/ra_proc_macro_srv/src/cli.rs new file mode 100644 index 000000000..c771f2b38 --- /dev/null +++ b/crates/ra_proc_macro_srv/src/cli.rs @@ -0,0 +1,56 @@ +//! Driver for proc macro server + +use crate::{expand_task, list_macros}; +use ra_proc_macro::msg::{self, Message}; + +use std::io; + +fn read_request() -> Result, io::Error> { + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + msg::Request::read(&mut stdin) +} + +fn write_response(res: Result) -> Result<(), io::Error> { + let msg: msg::Response = match res { + Ok(res) => res, + Err(err) => msg::Response::Error(msg::ResponseError { + code: msg::ErrorCode::ExpansionError, + message: err, + }), + }; + + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + msg.write(&mut stdout) +} + +pub fn run() { + loop { + let req = match read_request() { + Err(err) => { + eprintln!("Read message error on ra_proc_macro_srv: {}", err.to_string()); + continue; + } + Ok(None) => continue, + Ok(Some(req)) => req, + }; + + match req { + msg::Request::ListMacro(task) => { + if let Err(err) = + write_response(list_macros(&task).map(|it| msg::Response::ListMacro(it))) + { + eprintln!("Write message error on list macro: {}", err); + } + } + msg::Request::ExpansionMacro(task) => { + if let Err(err) = + write_response(expand_task(&task).map(|it| msg::Response::ExpansionMacro(it))) + { + eprintln!("Write message error on expansion macro: {}", err); + } + } + } + } +} diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/ra_proc_macro_srv/src/lib.rs index 59716cbb3..c62b0ed89 100644 --- a/crates/ra_proc_macro_srv/src/lib.rs +++ b/crates/ra_proc_macro_srv/src/lib.rs @@ -22,7 +22,7 @@ mod dylib; use proc_macro::bridge::client::TokenStream; use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; -pub fn expand_task(task: &ExpansionTask) -> Result { +pub(crate) fn expand_task(task: &ExpansionTask) -> Result { let expander = dylib::Expander::new(&task.lib) .expect(&format!("Cannot expand with provided libraries: ${:?}", &task.lib)); @@ -39,7 +39,7 @@ pub fn expand_task(task: &ExpansionTask) -> Result { } } -pub fn list_macros(task: &ListMacrosTask) -> Result { +pub(crate) fn list_macros(task: &ListMacrosTask) -> Result { let expander = dylib::Expander::new(&task.lib) .expect(&format!("Cannot expand with provided libraries: ${:?}", &task.lib)); @@ -53,5 +53,7 @@ pub fn list_macros(task: &ListMacrosTask) -> Result { } } +pub mod cli; + #[cfg(test)] mod tests; diff --git a/crates/ra_proc_macro_srv/src/main.rs b/crates/ra_proc_macro_srv/src/main.rs deleted file mode 100644 index 70743c1f4..000000000 --- a/crates/ra_proc_macro_srv/src/main.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Driver for proc macro server - -use ra_proc_macro::msg::{self, Message}; -use ra_proc_macro_srv::{expand_task, list_macros}; - -use std::io; - -fn read_request() -> Result, io::Error> { - let stdin = io::stdin(); - let mut stdin = stdin.lock(); - msg::Request::read(&mut stdin) -} - -fn write_response(res: Result) -> Result<(), io::Error> { - let msg: msg::Response = match res { - Ok(res) => res, - Err(err) => msg::Response::Error(msg::ResponseError { - code: msg::ErrorCode::ExpansionError, - message: err, - }), - }; - - let stdout = io::stdout(); - let mut stdout = stdout.lock(); - msg.write(&mut stdout) -} -fn main() { - loop { - let req = match read_request() { - Err(err) => { - eprintln!("Read message error on ra_proc_macro_srv: {}", err.to_string()); - continue; - } - Ok(None) => continue, - Ok(Some(req)) => req, - }; - - match req { - msg::Request::ListMacro(task) => { - if let Err(err) = - write_response(list_macros(&task).map(|it| msg::Response::ListMacro(it))) - { - eprintln!("Write message error on list macro: {}", err); - } - } - msg::Request::ExpansionMacro(task) => { - if let Err(err) = - write_response(expand_task(&task).map(|it| msg::Response::ExpansionMacro(it))) - { - eprintln!("Write message error on expansion macro: {}", err); - } - } - } - } -} diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index f5f773432..cee0248b6 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -46,7 +46,7 @@ ra_db = { path = "../ra_db" } hir = { path = "../ra_hir", package = "ra_hir" } hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } - +ra_proc_macro_srv = { path = "../ra_proc_macro_srv" } [target.'cfg(windows)'.dependencies] winapi = "0.3.8" diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs index ec93e9e4e..5e19253a6 100644 --- a/crates/rust-analyzer/src/bin/args.rs +++ b/crates/rust-analyzer/src/bin/args.rs @@ -45,6 +45,7 @@ pub(crate) enum Command { /// this would include the parser test files. all: bool, }, + ProcMacro, RunServer, Version, } @@ -264,6 +265,7 @@ ARGS: Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } } + "proc-macro" => Command::ProcMacro, _ => { eprintln!( "\ diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 5f614a013..28b67cfe2 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -51,6 +51,7 @@ fn main() -> Result<()> { cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? } + args::Command::ProcMacro => run_proc_macro_sv()?, args::Command::RunServer => run_server()?, args::Command::Version => println!("rust-analyzer {}", env!("REV")), } @@ -64,6 +65,11 @@ fn setup_logging() -> Result<()> { Ok(()) } +fn run_proc_macro_sv() -> Result<()> { + ra_proc_macro_srv::cli::run(); + Ok(()) +} + fn run_server() -> Result<()> { log::info!("lifecycle: server started"); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index dfda488fb..32a9ee339 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -73,7 +73,10 @@ pub(crate) fn load_cargo( let proc_macro_client = if !with_proc_macro { ProcMacroClient::dummy() } else { - ProcMacroClient::extern_process(Path::new("ra_proc_macro_srv")).unwrap() + let mut path = std::env::current_exe()?; + path.pop(); + path.push("rust-analyzer"); + ProcMacroClient::extern_process(&path, &["proc-macro"]).unwrap() }; let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs, &proc_macro_client); Ok((host, source_roots)) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 46a89b37e..2b45f1310 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -20,7 +20,7 @@ pub struct Config { pub with_sysroot: bool, pub publish_diagnostics: bool, pub lru_capacity: Option, - pub proc_macro_srv: Option, + pub proc_macro_srv: Option<(String, Vec)>, pub files: FilesConfig, pub notifications: NotificationsConfig, @@ -134,7 +134,11 @@ impl Config { match get::(value, "/procMacro/enabled") { Some(true) => { - set(value, "/procMacro/serverPath", &mut self.proc_macro_srv); + if let Ok(mut path) = std::env::current_exe() { + path.pop(); + path.push("rust-analyzer"); + self.proc_macro_srv = Some((path.to_string_lossy().to_string(), vec!["proc-macro".to_string()])); + } } _ => self.proc_macro_srv = None, } diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index b7142e83b..f2ad453fa 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs @@ -148,9 +148,9 @@ impl WorldState { let proc_macro_client = match &config.proc_macro_srv { None => ProcMacroClient::dummy(), - Some(srv) => { - let path = Path::new(&srv); - match ProcMacroClient::extern_process(path) { + Some((path, args)) => { + let path = std::path::Path::new(path); + match ProcMacroClient::extern_process(path, args) { Ok(it) => it, Err(err) => { log::error!( diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 26ab81a8f..1dd2676b6 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -692,13 +692,15 @@ pub fn foo(_input: TokenStream) -> TokenStream { "###, ) .with_config(|config| { + // FIXME: Use env!("CARGO_BIN_EXE_ra-analyzer") instead after + // https://github.com/rust-lang/cargo/pull/7697 landed let macro_srv_path = std::path::Path::new(std::env!("CARGO_MANIFEST_DIR")) - .join("../../target/debug/ra_proc_macro_srv") + .join("../../target/debug/rust-analyzer") .to_string_lossy() .to_string(); config.cargo.load_out_dirs_from_check = true; - config.proc_macro_srv = Some(macro_srv_path) + config.proc_macro_srv = Some((macro_srv_path, vec!["proc-macro".to_string()])); }) .root("foo") .root("bar") -- cgit v1.2.3