aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_proc_macro_srv
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-03 13:06:04 +0100
committerGitHub <[email protected]>2020-04-03 13:06:04 +0100
commit1a8779bce07281f1fbde1166ded75bc5acaa0f27 (patch)
tree3c69ce23117592f5442bcfdfc165820394b775a3 /crates/ra_proc_macro_srv
parentac91de1525662a602a1057709eb91a9b21ea3ac7 (diff)
parent9a2114b0dd6d3292216fa4d05e3c4cd219633f4b (diff)
Merge #3800
3800: Introduce ra_proc_macro_srv r=matklad a=edwin0cheng This PR add preliminary for server side of proc macro : 1. Add crate setup 2. IO for server side Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_proc_macro_srv')
-rw-r--r--crates/ra_proc_macro_srv/Cargo.toml24
-rw-r--r--crates/ra_proc_macro_srv/src/lib.rs21
-rw-r--r--crates/ra_proc_macro_srv/src/main.rs55
3 files changed, 100 insertions, 0 deletions
diff --git a/crates/ra_proc_macro_srv/Cargo.toml b/crates/ra_proc_macro_srv/Cargo.toml
new file mode 100644
index 000000000..fa2de2c91
--- /dev/null
+++ b/crates/ra_proc_macro_srv/Cargo.toml
@@ -0,0 +1,24 @@
1[package]
2edition = "2018"
3name = "ra_proc_macro_srv"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6publish = false
7
8[lib]
9doctest = false
10
11[dependencies]
12ra_tt = { path = "../ra_tt" }
13ra_mbe = { path = "../ra_mbe" }
14ra_proc_macro = { path = "../ra_proc_macro" }
15
16serde_derive = "1.0.104"
17serde = "1.0.104"
18serde_json = "1.0.48"
19libloading = "0.5.2"
20goblin = "0.2.0"
21
22[dev-dependencies]
23cargo_metadata = "0.9.1"
24difference = "2.0.0"
diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/ra_proc_macro_srv/src/lib.rs
new file mode 100644
index 000000000..f77be1475
--- /dev/null
+++ b/crates/ra_proc_macro_srv/src/lib.rs
@@ -0,0 +1,21 @@
1//! RA Proc Macro Server
2//!
3//! This library is able to call compiled Rust custom derive dynamic libraries on arbitrary code.
4//! The general idea here is based on https://github.com/fedochet/rust-proc-macro-expander.
5//!
6//! But we change some several design for fitting RA needs:
7//!
8//! * We use `ra_tt` for proc-macro `TokenStream` server, it is easy to manipute and interact with
9//! RA then proc-macro2 token stream.
10//! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable`
11//! rustc rather than `unstable`. (Although in gerenal ABI compatibility is still an issue)
12
13use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask};
14
15pub fn expand_task(_task: &ExpansionTask) -> Result<ExpansionResult, String> {
16 unimplemented!()
17}
18
19pub fn list_macros(_task: &ListMacrosTask) -> Result<ListMacrosResult, String> {
20 unimplemented!()
21}
diff --git a/crates/ra_proc_macro_srv/src/main.rs b/crates/ra_proc_macro_srv/src/main.rs
new file mode 100644
index 000000000..70743c1f4
--- /dev/null
+++ b/crates/ra_proc_macro_srv/src/main.rs
@@ -0,0 +1,55 @@
1//! Driver for proc macro server
2
3use ra_proc_macro::msg::{self, Message};
4use ra_proc_macro_srv::{expand_task, list_macros};
5
6use std::io;
7
8fn read_request() -> Result<Option<msg::Request>, io::Error> {
9 let stdin = io::stdin();
10 let mut stdin = stdin.lock();
11 msg::Request::read(&mut stdin)
12}
13
14fn write_response(res: Result<msg::Response, String>) -> Result<(), io::Error> {
15 let msg: msg::Response = match res {
16 Ok(res) => res,
17 Err(err) => msg::Response::Error(msg::ResponseError {
18 code: msg::ErrorCode::ExpansionError,
19 message: err,
20 }),
21 };
22
23 let stdout = io::stdout();
24 let mut stdout = stdout.lock();
25 msg.write(&mut stdout)
26}
27fn main() {
28 loop {
29 let req = match read_request() {
30 Err(err) => {
31 eprintln!("Read message error on ra_proc_macro_srv: {}", err.to_string());
32 continue;
33 }
34 Ok(None) => continue,
35 Ok(Some(req)) => req,
36 };
37
38 match req {
39 msg::Request::ListMacro(task) => {
40 if let Err(err) =
41 write_response(list_macros(&task).map(|it| msg::Response::ListMacro(it)))
42 {
43 eprintln!("Write message error on list macro: {}", err);
44 }
45 }
46 msg::Request::ExpansionMacro(task) => {
47 if let Err(err) =
48 write_response(expand_task(&task).map(|it| msg::Response::ExpansionMacro(it)))
49 {
50 eprintln!("Write message error on expansion macro: {}", err);
51 }
52 }
53 }
54 }
55}