From 00d9465e44e9174d4661224f08d50e80f059abd4 Mon Sep 17 00:00:00 2001 From: Piotr Figiela <77412592+Draggu@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:58:16 +0200 Subject: [PATCH] Add Proc macro server commit-id:2ceebe3f --- Cargo.lock | 11 +++ scarb/Cargo.toml | 2 + scarb/src/ops/proc_macro_server/connection.rs | 98 +++++++++++++++++++ scarb/src/ops/proc_macro_server/mod.rs | 11 ++- 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 scarb/src/ops/proc_macro_server/connection.rs diff --git a/Cargo.lock b/Cargo.lock index 6d3211e00..d40845a52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4208,6 +4208,15 @@ dependencies = [ "toml_edit 0.21.1", ] +[[package]] +name = "proc-macro-server-api" +version = "2.8.4" +dependencies = [ + "cairo-lang-macro", + "serde", + "serde_json", +] + [[package]] name = "proc-macro2" version = "1.0.88" @@ -4635,6 +4644,7 @@ dependencies = [ "clap", "convert_case", "create-output-dir", + "crossbeam-channel", "data-encoding", "deno_task_shell", "derive_builder", @@ -4661,6 +4671,7 @@ dependencies = [ "pathdiff", "petgraph", "predicates", + "proc-macro-server-api", "ra_ap_toolchain", "redb", "reqwest", diff --git a/scarb/Cargo.toml b/scarb/Cargo.toml index 5f887e927..11639d830 100644 --- a/scarb/Cargo.toml +++ b/scarb/Cargo.toml @@ -37,6 +37,7 @@ camino.workspace = true clap.workspace = true convert_case.workspace = true create-output-dir = { path = "../utils/create-output-dir" } +crossbeam-channel = "0.5.13" data-encoding.workspace = true deno_task_shell.workspace = true derive_builder.workspace = true @@ -56,6 +57,7 @@ libloading.workspace = true once_cell.workspace = true pathdiff.workspace = true petgraph.workspace = true +proc-macro-server-api = { path = "../utils/proc-macro-server-api" } ra_ap_toolchain.workspace = true redb.workspace = true reqwest.workspace = true diff --git a/scarb/src/ops/proc_macro_server/connection.rs b/scarb/src/ops/proc_macro_server/connection.rs new file mode 100644 index 000000000..e2b444f08 --- /dev/null +++ b/scarb/src/ops/proc_macro_server/connection.rs @@ -0,0 +1,98 @@ +use crossbeam_channel::{Receiver, Sender}; +use proc_macro_server_api::{RpcRequest, RpcResponse}; +use std::{ + io::{BufRead, Write}, + thread::JoinHandle, +}; + +pub struct Connection { + pub sender: Sender, + pub receiver: Receiver, + io_threads: IoThreads, +} + +impl Connection { + pub fn new() -> Self { + let (reader_sender, reader_receiver) = crossbeam_channel::bounded(0); + let (writer_sender, writer_receiver) = crossbeam_channel::bounded(0); + + let reader = std::thread::spawn(move || { + let stdin = std::io::stdin(); + let mut stdin = stdin.lock(); + + let mut line = String::new(); + + loop { + line.clear(); + + if stdin.read_line(&mut line).is_err() { + eprintln!("Error occurred while reading from stdin"); + + break; + } + + if line.is_empty() { + continue; + } + + let Ok(request) = serde_json::from_str(&line) else { + eprintln!("Error occurred while deserializing request, used input:\n{line}"); + + break; + }; + + if reader_sender.send(request).is_err() { + eprintln!("Error occurred while sending request to worker threads"); + + break; + } + } + }); + + let writer = std::thread::spawn(move || { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + + for response in writer_receiver { + // This should not fail. + let mut res = serde_json::to_vec(&response).unwrap(); + + res.push(b'\n'); + + if stdout.write_all(&res).is_err() { + eprintln!("Error occurred while writing to stdout"); + + break; + } + + if stdout.flush().is_err() { + eprintln!("Error occurred while flushing stdout"); + + break; + } + } + }); + + let io_threads = IoThreads { reader, writer }; + + Self { + sender: writer_sender, + receiver: reader_receiver, + io_threads, + } + } + + pub fn join(self) { + if let Err(err) = self.io_threads.reader.join() { + std::panic::panic_any(err); + } + if let Err(err) = self.io_threads.writer.join() { + std::panic::panic_any(err); + } + } +} + +struct IoThreads { + reader: JoinHandle<()>, + writer: JoinHandle<()>, +} diff --git a/scarb/src/ops/proc_macro_server/mod.rs b/scarb/src/ops/proc_macro_server/mod.rs index 9f1fb9d5e..3cc30ea1e 100644 --- a/scarb/src/ops/proc_macro_server/mod.rs +++ b/scarb/src/ops/proc_macro_server/mod.rs @@ -1,6 +1,15 @@ use crate::compiler::plugin::proc_macro::ProcMacroHost; use anyhow::Result; +use connection::Connection; + +mod connection; pub fn start_proc_macro_server(proc_macros: ProcMacroHost) -> Result<()> { - unimplemented!() + let connection = Connection::new(); + + //TODO + + connection.join(); + + Ok(()) }