From 22e33f308a7dfe924bf2d10f9041e91cec1349a0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 12 Apr 2020 18:25:31 +0800 Subject: Add with-proc-macro in bench ,stats and diagnositcs --- crates/rust-analyzer/src/bin/args.rs | 22 +++++++++++++++++++--- crates/rust-analyzer/src/bin/main.rs | 16 ++++++++++++---- crates/rust-analyzer/src/cli/analysis_bench.rs | 3 ++- crates/rust-analyzer/src/cli/analysis_stats.rs | 3 ++- crates/rust-analyzer/src/cli/diagnostics.rs | 9 +++++++-- crates/rust-analyzer/src/cli/load_cargo.rs | 9 +++++++-- 6 files changed, 49 insertions(+), 13 deletions(-) diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs index f5981588a..ec93e9e4e 100644 --- a/crates/rust-analyzer/src/bin/args.rs +++ b/crates/rust-analyzer/src/bin/args.rs @@ -29,15 +29,18 @@ pub(crate) enum Command { with_deps: bool, path: PathBuf, load_output_dirs: bool, + with_proc_macro: bool, }, Bench { path: PathBuf, what: BenchWhat, load_output_dirs: bool, + with_proc_macro: bool, }, Diagnostics { path: PathBuf, load_output_dirs: bool, + with_proc_macro: bool, /// Include files which are not modules. In rust-analyzer /// this would include the parser test files. all: bool, @@ -148,6 +151,7 @@ FLAGS: -h, --help Prints help information --memory-usage --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis + --with-proc-macro Use ra-proc-macro-srv for proc-macro expanding -v, --verbose -q, --quiet @@ -165,6 +169,7 @@ ARGS: let only: Option = matches.opt_value_from_str(["-o", "--only"])?; let with_deps: bool = matches.contains("--with-deps"); let load_output_dirs = matches.contains("--load-output-dirs"); + let with_proc_macro = matches.contains("--with-proc-macro"); let path = { let mut trailing = matches.free()?; if trailing.len() != 1 { @@ -173,7 +178,15 @@ ARGS: trailing.pop().unwrap().into() }; - Command::Stats { randomize, memory_usage, only, with_deps, path, load_output_dirs } + Command::Stats { + randomize, + memory_usage, + only, + with_deps, + path, + load_output_dirs, + with_proc_macro, + } } "analysis-bench" => { if matches.contains(["-h", "--help"]) { @@ -187,6 +200,7 @@ USAGE: FLAGS: -h, --help Prints help information --load-output-dirs Load OUT_DIR values by running `cargo check` before analysis + --with-proc-macro Use ra-proc-macro-srv for proc-macro expanding -v, --verbose OPTIONS: @@ -214,7 +228,8 @@ ARGS: ), }; let load_output_dirs = matches.contains("--load-output-dirs"); - Command::Bench { path, what, load_output_dirs } + let with_proc_macro = matches.contains("--with-proc-macro"); + Command::Bench { path, what, load_output_dirs, with_proc_macro } } "diagnostics" => { if matches.contains(["-h", "--help"]) { @@ -237,6 +252,7 @@ ARGS: } let load_output_dirs = matches.contains("--load-output-dirs"); + let with_proc_macro = matches.contains("--with-proc-macro"); let all = matches.contains("--all"); let path = { let mut trailing = matches.free()?; @@ -246,7 +262,7 @@ ARGS: trailing.pop().unwrap().into() }; - Command::Diagnostics { path, load_output_dirs, all } + Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } } _ => { eprintln!( diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 7cfc44f01..5f614a013 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -25,6 +25,7 @@ fn main() -> Result<()> { with_deps, path, load_output_dirs, + with_proc_macro, } => cli::analysis_stats( args.verbosity, memory_usage, @@ -33,14 +34,21 @@ fn main() -> Result<()> { with_deps, randomize, load_output_dirs, + with_proc_macro, )?, - args::Command::Bench { path, what, load_output_dirs } => { - cli::analysis_bench(args.verbosity, path.as_ref(), what, load_output_dirs)? + args::Command::Bench { path, what, load_output_dirs, with_proc_macro } => { + cli::analysis_bench( + args.verbosity, + path.as_ref(), + what, + load_output_dirs, + with_proc_macro, + )? } - args::Command::Diagnostics { path, load_output_dirs, all } => { - cli::diagnostics(path.as_ref(), load_output_dirs, all)? + args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => { + cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? } args::Command::RunServer => run_server()?, diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 7667873d5..6147ae207 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -47,12 +47,13 @@ pub fn analysis_bench( path: &Path, what: BenchWhat, load_output_dirs: bool, + with_proc_macro: bool, ) -> Result<()> { ra_prof::init(); let start = Instant::now(); eprint!("loading: "); - let (mut host, roots) = load_cargo(path, load_output_dirs)?; + let (mut host, roots) = load_cargo(path, load_output_dirs, with_proc_macro)?; let db = host.raw_database(); eprintln!("{:?}\n", start.elapsed()); diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index e9ee0b888..d442cbd63 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -25,9 +25,10 @@ pub fn analysis_stats( with_deps: bool, randomize: bool, load_output_dirs: bool, + with_proc_macro: bool, ) -> Result<()> { let db_load_time = Instant::now(); - let (mut host, roots) = load_cargo(path, load_output_dirs)?; + let (mut host, roots) = load_cargo(path, load_output_dirs, with_proc_macro)?; let db = host.raw_database(); println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed()); let analysis_time = Instant::now(); diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs index 92664b415..60daefa3e 100644 --- a/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/crates/rust-analyzer/src/cli/diagnostics.rs @@ -9,8 +9,13 @@ use std::{collections::HashSet, path::Path}; use crate::cli::{load_cargo::load_cargo, Result}; use hir::Semantics; -pub fn diagnostics(path: &Path, load_output_dirs: bool, all: bool) -> Result<()> { - let (host, roots) = load_cargo(path, load_output_dirs)?; +pub fn diagnostics( + path: &Path, + load_output_dirs: bool, + with_proc_macro: bool, + all: bool, +) -> Result<()> { + let (host, roots) = load_cargo(path, load_output_dirs, with_proc_macro)?; let db = host.raw_database(); let analysis = host.analysis(); let semantics = Semantics::new(db); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 43062ea10..f70d92c7f 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -25,6 +25,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { pub(crate) fn load_cargo( root: &Path, load_out_dirs_from_check: bool, + with_proc_macro: bool, ) -> Result<(AnalysisHost, FxHashMap)> { let root = std::env::current_dir()?.join(root); let ws = ProjectWorkspace::discover( @@ -69,7 +70,11 @@ pub(crate) fn load_cargo( }) .collect::>(); - let proc_macro_client = ProcMacroClient::dummy(); + let proc_macro_client = if with_proc_macro { + ProcMacroClient::dummy() + } else { + ProcMacroClient::extern_process(Path::new("ra_proc_macro_srv")).unwrap() + }; let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs, &proc_macro_client); Ok((host, source_roots)) } @@ -175,7 +180,7 @@ mod tests { #[test] fn test_loading_rust_analyzer() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); - let (host, _roots) = load_cargo(path, false).unwrap(); + let (host, _roots) = load_cargo(path, false, false).unwrap(); let n_crates = Crate::all(host.raw_database()).len(); // RA has quite a few crates, but the exact count doesn't matter assert!(n_crates > 20); -- cgit v1.2.3 From a4b0ce07f80773146c72004befc77be4e576c677 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 13 Apr 2020 00:05:33 +0800 Subject: Add config for proc_macro --- crates/rust-analyzer/src/cli/load_cargo.rs | 2 +- crates/rust-analyzer/src/config.rs | 8 ++++++++ crates/rust-analyzer/src/world.rs | 2 ++ editors/code/package.json | 10 ++++++++++ editors/code/src/config.ts | 1 + 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index f70d92c7f..dfda488fb 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -70,7 +70,7 @@ pub(crate) fn load_cargo( }) .collect::>(); - let proc_macro_client = if with_proc_macro { + let proc_macro_client = if !with_proc_macro { ProcMacroClient::dummy() } else { ProcMacroClient::extern_process(Path::new("ra_proc_macro_srv")).unwrap() diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 4734df16a..46a89b37e 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -131,6 +131,14 @@ impl Config { set(value, "/cargo/allFeatures", &mut self.cargo.all_features); set(value, "/cargo/features", &mut self.cargo.features); set(value, "/cargo/loadOutDirsFromCheck", &mut self.cargo.load_out_dirs_from_check); + + match get::(value, "/procMacro/enabled") { + Some(true) => { + set(value, "/procMacro/serverPath", &mut self.proc_macro_srv); + } + _ => self.proc_macro_srv = None, + } + match get::>(value, "/rustfmt/overrideCommand") { Some(mut args) if !args.is_empty() => { let command = args.remove(0); diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index 6c42e1d76..b7142e83b 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs @@ -64,6 +64,7 @@ pub struct WorldState { pub latest_requests: Arc>, pub flycheck: Option, pub diagnostics: DiagnosticCollection, + pub proc_macro_client: ProcMacroClient, } /// An immutable snapshot of the world's state at a point in time. @@ -192,6 +193,7 @@ impl WorldState { latest_requests: Default::default(), flycheck, diagnostics: Default::default(), + proc_macro_client, } } diff --git a/editors/code/package.json b/editors/code/package.json index 5f73c8d83..d39a9b6d8 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -388,6 +388,16 @@ "description": "Enable logging of VS Code extensions itself", "type": "boolean", "default": false + }, + "rust-analyzer.procMacro.enabled": { + "description": "Enable Proc macro support, cargo.loadOutDirsFromCheck must be enabled.", + "type": "boolean", + "default": false + }, + "rust-analyzer.procMacro.serverPath": { + "description": "Proc macro server path", + "type": "string", + "default": "ra_proc_macro_srv" } } }, diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 35a05131c..3b2eec8ba 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -12,6 +12,7 @@ export class Config { private readonly requiresReloadOpts = [ "serverPath", "cargo", + "procMacro", "files", "highlighting", "updates.channel", -- cgit v1.2.3 From ca7dc69a8e87883c6a0c9df88c936fa2a4658c7b Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 13 Apr 2020 00:05:45 +0800 Subject: Add tests for proc_macro --- .github/workflows/ci.yaml | 4 ++ crates/rust-analyzer/tests/heavy_tests/main.rs | 89 +++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 00f299ff1..13a11c95b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,6 +85,10 @@ jobs: - name: Compile run: cargo test --no-run + # We have to build ra_proc_macro_srv first for running related heavy tests + - name: Build ra_proc_macro_srv + run: cargo build -p ra_proc_macro_srv + - name: Test run: cargo test diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 638813311..26ab81a8f 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -9,7 +9,7 @@ use lsp_types::{ }; use rust_analyzer::req::{ CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, - Formatting, GotoDefinition, OnEnter, Runnables, RunnablesParams, + Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams, }; use serde_json::json; use tempfile::TempDir; @@ -625,3 +625,90 @@ fn main() { message(); } )); assert!(format!("{}", res).contains("hello.rs")); } + +#[test] +fn resolve_proc_macro() { + if skip_slow_tests() { + return; + } + let server = Project::with_fixture( + r###" +//- foo/Cargo.toml +[package] +name = "foo" +version = "0.0.0" +edition = "2018" +[dependencies] +bar = {path = "../bar"} + +//- foo/src/main.rs +use bar::Bar; +trait Bar { + fn bar(); +} +#[derive(Bar)] +struct Foo {} +fn main() { + Foo::bar(); +} + +//- bar/Cargo.toml +[package] +name = "bar" +version = "0.0.0" +edition = "2018" + +[lib] +proc-macro = true + +//- bar/src/lib.rs +extern crate proc_macro; +use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; +macro_rules! t { + ($n:literal) => { + TokenTree::from(Ident::new($n, Span::call_site())) + }; + ({}) => { + TokenTree::from(Group::new(Delimiter::Brace, TokenStream::new())) + }; + (()) => { + TokenTree::from(Group::new(Delimiter::Parenthesis, TokenStream::new())) + }; +} +#[proc_macro_derive(Bar)] +pub fn foo(_input: TokenStream) -> TokenStream { + // We hard code the output here for preventing to use any deps + let mut res = TokenStream::new(); + + // impl Bar for Foo { fn bar() {} } + let mut tokens = vec![t!("impl"), t!("Bar"), t!("for"), t!("Foo")]; + let mut fn_stream = TokenStream::new(); + fn_stream.extend(vec![t!("fn"), t!("bar"), t!(()), t!({})]); + tokens.push(Group::new(Delimiter::Brace, fn_stream).into()); + res.extend(tokens); + res +} + +"###, + ) + .with_config(|config| { + let macro_srv_path = std::path::Path::new(std::env!("CARGO_MANIFEST_DIR")) + .join("../../target/debug/ra_proc_macro_srv") + .to_string_lossy() + .to_string(); + + config.cargo.load_out_dirs_from_check = true; + config.proc_macro_srv = Some(macro_srv_path) + }) + .root("foo") + .root("bar") + .server(); + server.wait_until_workspace_is_loaded(); + let res = server.send_request::(TextDocumentPositionParams::new( + server.doc_id("foo/src/main.rs"), + Position::new(7, 9), + )); + + let value = res.get("contents").unwrap().get("value").unwrap().to_string(); + assert_eq!(value, r#""```rust\nfoo::Bar\nfn bar()\n```""#) +} -- cgit v1.2.3 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 --- .github/workflows/ci.yaml | 6 +-- Cargo.lock | 1 + 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 ++- editors/code/package.json | 5 --- 15 files changed, 100 insertions(+), 79 deletions(-) create mode 100644 crates/ra_proc_macro_srv/src/cli.rs delete mode 100644 crates/ra_proc_macro_srv/src/main.rs diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 13a11c95b..9068064f7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,9 +85,9 @@ jobs: - name: Compile run: cargo test --no-run - # We have to build ra_proc_macro_srv first for running related heavy tests - - name: Build ra_proc_macro_srv - run: cargo build -p ra_proc_macro_srv + # We have to build rust-analyzer first for running related heavy tests + - name: Build rust-analyzer + run: cargo build -p rust-analyzer - name: Test run: cargo test diff --git a/Cargo.lock b/Cargo.lock index 01fa64e6f..8e204d39f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1341,6 +1341,7 @@ dependencies = [ "ra_hir_def", "ra_hir_ty", "ra_ide", + "ra_proc_macro_srv", "ra_prof", "ra_project_model", "ra_syntax", 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") diff --git a/editors/code/package.json b/editors/code/package.json index d39a9b6d8..5ce59e54a 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -393,11 +393,6 @@ "description": "Enable Proc macro support, cargo.loadOutDirsFromCheck must be enabled.", "type": "boolean", "default": false - }, - "rust-analyzer.procMacro.serverPath": { - "description": "Proc macro server path", - "type": "string", - "default": "ra_proc_macro_srv" } } }, -- cgit v1.2.3 From b4c5ee33ae128df4e82c992d0c13f6c9df0f9f02 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 17 Apr 2020 04:08:01 +0800 Subject: Fix extern_process args --- crates/ra_proc_macro/src/lib.rs | 11 ++++++++--- crates/ra_proc_macro/src/process.rs | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs index 14a675db2..b200fd126 100644 --- a/crates/ra_proc_macro/src/lib.rs +++ b/crates/ra_proc_macro/src/lib.rs @@ -12,6 +12,7 @@ pub mod msg; use process::{ProcMacroProcessSrv, ProcMacroProcessThread}; use ra_tt::{SmolStr, Subtree}; use std::{ + ffi::OsStr, path::{Path, PathBuf}, sync::Arc, }; @@ -56,10 +57,14 @@ pub struct ProcMacroClient { } impl ProcMacroClient { - pub fn extern_process>( + pub fn extern_process( process_path: &Path, - args: &[T], - ) -> Result { + args: I, + ) -> Result + where + I: IntoIterator, + S: AsRef, + { 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 b5e8493ac..f851570bc 100644 --- a/crates/ra_proc_macro/src/process.rs +++ b/crates/ra_proc_macro/src/process.rs @@ -9,6 +9,7 @@ use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTas use io::{BufRead, BufReader}; use std::{ convert::{TryFrom, TryInto}, + ffi::OsStr, io::{self, Write}, path::{Path, PathBuf}, process::{Child, Command, Stdio}, @@ -44,9 +45,13 @@ impl Drop for Process { } impl Process { - fn run>(process_path: &Path, args: &[T]) -> Result { + fn run(process_path: &Path, args: I) -> Result + where + I: IntoIterator, + S: AsRef, + { let child = Command::new(process_path.clone()) - .args(args.iter().map(|it| it.as_ref())) + .args(args) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::null()) @@ -75,10 +80,14 @@ impl Process { } impl ProcMacroProcessSrv { - pub fn run>( + pub fn run( process_path: &Path, - args: &[T], - ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error> { + args: I, + ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error> + where + I: IntoIterator, + S: AsRef, + { let process = Process::run(process_path, args)?; let (task_tx, task_rx) = bounded(0); -- cgit v1.2.3 From 16a74cfd234e94d383b0ef067fb6a3c651ed9624 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 17 Apr 2020 04:11:49 +0800 Subject: Remove ci changes --- .github/workflows/ci.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9068064f7..00f299ff1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,10 +85,6 @@ jobs: - name: Compile run: cargo test --no-run - # We have to build rust-analyzer first for running related heavy tests - - name: Build rust-analyzer - run: cargo build -p rust-analyzer - - name: Test run: cargo test -- cgit v1.2.3