Unnamed repository; edit this file 'description' to name the repository.
remove internal callbacks, and move callback to rust-analyzer level
| -rw-r--r-- | .github/workflows/ci.yaml | 5 | ||||
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | crates/load-cargo/src/lib.rs | 22 | ||||
| -rw-r--r-- | crates/proc-macro-api/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/proc-macro-api/src/bidirectional_protocol.rs | 85 | ||||
| -rw-r--r-- | crates/proc-macro-api/src/legacy_protocol.rs | 2 | ||||
| -rw-r--r-- | crates/proc-macro-api/src/lib.rs | 15 | ||||
| -rw-r--r-- | crates/proc-macro-api/src/process.rs | 36 | ||||
| -rw-r--r-- | crates/proc-macro-srv-cli/src/main.rs | 14 |
9 files changed, 83 insertions, 98 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 81ca025498..e817f770a4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,9 +71,8 @@ jobs: - name: Test run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet - # FIXME: This is temporarily disable, more info: https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/Non-generic.20spans/with/564604549 - # - name: Check salsa dependency - # run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" + - name: Check salsa dependency + run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" rust: if: github.repository == 'rust-lang/rust-analyzer' diff --git a/Cargo.lock b/Cargo.lock index 060a62b112..7d133f9949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1836,7 +1836,6 @@ dependencies = [ name = "proc-macro-api" version = "0.0.0" dependencies = [ - "base-db", "indexmap", "intern", "paths", diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index e043e4ac76..a7b22b0d6a 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -23,11 +23,17 @@ use ide_db::{ prime_caches, }; use itertools::Itertools; -use proc_macro_api::{MacroDylib, ProcMacroClient}; +use proc_macro_api::{ + MacroDylib, ProcMacroClient, + bidirectional_protocol::{ + msg::{SubRequest, SubResponse}, + reject_subrequests, + }, +}; use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ - AbsPath, AbsPathBuf, VfsPath, + AbsPath, AbsPathBuf, FileId, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, }; @@ -427,7 +433,7 @@ pub fn load_proc_macro( ) -> ProcMacroLoadResult { let res: Result<Vec<_>, _> = (|| { let dylib = MacroDylib::new(path.to_path_buf()); - let vec = server.load_dylib(dylib).map_err(|e| { + let vec = server.load_dylib(dylib, Some(&mut reject_subrequests)).map_err(|e| { ProcMacroLoadingError::ProcMacroSrvError(format!("{e}").into_boxed_str()) })?; if vec.is_empty() { @@ -533,8 +539,15 @@ impl ProcMacroExpander for Expander { mixed_site: Span, current_dir: String, ) -> Result<tt::TopSubtree<Span>, ProcMacroExpansionError> { + let mut cb = |req| match req { + SubRequest::SourceText { file_id, start, end } => { + let file = FileId::from_raw(file_id); + let text = db.file_text(file).text(db); + let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); + Ok(SubResponse::SourceTextResult { text: slice }) + } + }; match self.0.expand( - db, subtree.view(), attrs.map(|attrs| attrs.view()), env.clone().into(), @@ -542,6 +555,7 @@ impl ProcMacroExpander for Expander { call_site, mixed_site, current_dir, + Some(&mut cb), ) { Ok(Ok(subtree)) => Ok(subtree), Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)), diff --git a/crates/proc-macro-api/Cargo.toml b/crates/proc-macro-api/Cargo.toml index 7e56d68964..4de1a3e5dd 100644 --- a/crates/proc-macro-api/Cargo.toml +++ b/crates/proc-macro-api/Cargo.toml @@ -19,7 +19,6 @@ serde_json = { workspace = true, features = ["unbounded_depth"] } tracing.workspace = true rustc-hash.workspace = true indexmap.workspace = true -base-db.workspace = true # local deps paths = { workspace = true, features = ["serde1"] } diff --git a/crates/proc-macro-api/src/bidirectional_protocol.rs b/crates/proc-macro-api/src/bidirectional_protocol.rs index 4cb6a1d90f..bd74738bbd 100644 --- a/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -5,9 +5,8 @@ use std::{ sync::Arc, }; -use base_db::SourceDatabase; use paths::AbsPath; -use span::{FileId, Span}; +use span::Span; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, @@ -29,16 +28,14 @@ use crate::{ pub mod msg; -pub trait ClientCallbacks { - fn handle_sub_request(&mut self, req: SubRequest) -> Result<SubResponse, ServerError>; -} +pub type SubCallback<'a> = &'a mut dyn FnMut(SubRequest) -> Result<SubResponse, ServerError>; pub fn run_conversation<C: Codec>( writer: &mut dyn Write, reader: &mut dyn BufRead, buf: &mut C::Buf, msg: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result<BidirectionalMessage, ServerError> { let encoded = C::encode(&msg).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; @@ -59,7 +56,7 @@ pub fn run_conversation<C: Codec>( return Ok(BidirectionalMessage::Response(response)); } BidirectionalMessage::SubRequest(sr) => { - let resp = callbacks.handle_sub_request(sr)?; + let resp = callback(sr)?; let reply = BidirectionalMessage::SubResponse(resp); let encoded = C::encode(&reply).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?; @@ -86,19 +83,13 @@ fn wrap_decode(err: io::Error) -> ServerError { ServerError { message: "failed to decode message".into(), io: Some(Arc::new(err)) } } -pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result<u32, ServerError> { +pub(crate) fn version_check( + srv: &ProcMacroServerProcess, + callback: SubCallback<'_>, +) -> Result<u32, ServerError> { let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result<SubResponse, ServerError> { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::ApiVersionCheck(version)) => Ok(version), @@ -111,21 +102,13 @@ pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result<u32, ServerE /// Enable support for rust-analyzer span mode if the server supports it. pub(crate) fn enable_rust_analyzer_spans( srv: &ProcMacroServerProcess, + callback: SubCallback<'_>, ) -> Result<SpanMode, ServerError> { let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer, })); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result<SubResponse, ServerError> { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::SetConfig(ServerConfig { span_mode })) => { @@ -139,21 +122,13 @@ pub(crate) fn enable_rust_analyzer_spans( pub(crate) fn find_proc_macros( srv: &ProcMacroServerProcess, dylib_path: &AbsPath, + callback: SubCallback<'_>, ) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> { let request = BidirectionalMessage::Request(Request::ListMacros { dylib_path: dylib_path.to_path_buf().into(), }); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result<SubResponse, ServerError> { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::ListMacros(it)) => Ok(it), @@ -163,7 +138,6 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, - db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option<tt::SubtreeView<'_, Span>>, env: Vec<(String, String)>, @@ -171,6 +145,7 @@ pub(crate) fn expand( call_site: Span, mixed_site: Span, current_dir: String, + callback: SubCallback<'_>, ) -> Result<Result<tt::TopSubtree<span::SpanData<span::SyntaxContext>>, String>, crate::ServerError> { let version = proc_macro.process.version(); @@ -201,27 +176,7 @@ pub(crate) fn expand( current_dir: Some(current_dir), }))); - struct Callbacks<'de> { - db: &'de dyn SourceDatabase, - } - impl<'db> ClientCallbacks for Callbacks<'db> { - fn handle_sub_request(&mut self, req: SubRequest) -> Result<SubResponse, ServerError> { - match req { - SubRequest::SourceText { file_id, start, end } => { - let file = FileId::from_raw(file_id); - let text = self.db.file_text(file).text(self.db); - - let slice = text.get(start as usize..end as usize).map(|s| s.to_owned()); - - Ok(SubResponse::SourceTextResult { text: slice }) - } - } - } - } - - let mut callbacks = Callbacks { db }; - - let response_payload = run_request(&proc_macro.process, task, &mut callbacks)?; + let response_payload = run_request(&proc_macro.process, task, callback)?; match response_payload { BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it @@ -253,15 +208,19 @@ pub(crate) fn expand( fn run_request( srv: &ProcMacroServerProcess, msg: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result<BidirectionalMessage, ServerError> { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } if srv.use_postcard() { - srv.run_bidirectional::<PostcardProtocol>(msg, callbacks) + srv.run_bidirectional::<PostcardProtocol>(msg, callback) } else { - srv.run_bidirectional::<JsonProtocol>(msg, callbacks) + srv.run_bidirectional::<JsonProtocol>(msg, callback) } } + +pub fn reject_subrequests(req: SubRequest) -> Result<SubResponse, ServerError> { + Err(ServerError { message: format!("{req:?} sub-request not supported here"), io: None }) +} diff --git a/crates/proc-macro-api/src/legacy_protocol.rs b/crates/proc-macro-api/src/legacy_protocol.rs index 81a9f39181..0d16b60025 100644 --- a/crates/proc-macro-api/src/legacy_protocol.rs +++ b/crates/proc-macro-api/src/legacy_protocol.rs @@ -7,7 +7,6 @@ use std::{ sync::Arc, }; -use base_db::SourceDatabase; use paths::AbsPath; use span::Span; @@ -78,7 +77,6 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, - _db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option<tt::SubtreeView<'_, Span>>, env: Vec<(String, String)>, diff --git a/crates/proc-macro-api/src/lib.rs b/crates/proc-macro-api/src/lib.rs index 7b9b5b39ab..0ee0c3afb5 100644 --- a/crates/proc-macro-api/src/lib.rs +++ b/crates/proc-macro-api/src/lib.rs @@ -21,14 +21,13 @@ pub mod legacy_protocol; mod process; pub mod transport; -use base_db::SourceDatabase; use paths::{AbsPath, AbsPathBuf}; use semver::Version; use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use std::{fmt, io, sync::Arc, time::SystemTime}; -use crate::process::ProcMacroServerProcess; pub use crate::transport::codec::Codec; +use crate::{bidirectional_protocol::SubCallback, process::ProcMacroServerProcess}; /// The versions of the server protocol pub mod version { @@ -143,9 +142,13 @@ impl ProcMacroClient { } /// Loads a proc-macro dylib into the server process returning a list of `ProcMacro`s loaded. - pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> { + pub fn load_dylib( + &self, + dylib: MacroDylib, + callback: Option<SubCallback<'_>>, + ) -> Result<Vec<ProcMacro>, ServerError> { let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let macros = self.process.find_proc_macros(&dylib.path)?; + let macros = self.process.find_proc_macros(&dylib.path, callback)?; let dylib_path = Arc::new(dylib.path); let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) @@ -219,7 +222,6 @@ impl ProcMacro { /// This includes span information and environmental context. pub fn expand( &self, - db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option<tt::SubtreeView<'_, Span>>, env: Vec<(String, String)>, @@ -227,6 +229,7 @@ impl ProcMacro { call_site: Span, mixed_site: Span, current_dir: String, + callback: Option<SubCallback<'_>>, ) -> Result<Result<tt::TopSubtree<Span>, String>, ServerError> { let (mut subtree, mut attr) = (subtree, attr); let (mut subtree_changed, mut attr_changed); @@ -243,7 +246,6 @@ impl ProcMacro { } self.process.expand( - db, self, subtree, attr, @@ -252,6 +254,7 @@ impl ProcMacro { call_site, mixed_site, current_dir, + callback, ) } } diff --git a/crates/proc-macro-api/src/process.rs b/crates/proc-macro-api/src/process.rs index 6d40250012..01de8e98ff 100644 --- a/crates/proc-macro-api/src/process.rs +++ b/crates/proc-macro-api/src/process.rs @@ -7,7 +7,6 @@ use std::{ sync::{Arc, Mutex, OnceLock}, }; -use base_db::SourceDatabase; use paths::AbsPath; use semver::Version; use span::Span; @@ -15,7 +14,7 @@ use stdx::JodChild; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, - bidirectional_protocol::{self, ClientCallbacks, msg::BidirectionalMessage}, + bidirectional_protocol::{self, SubCallback, msg::BidirectionalMessage, reject_subrequests}, legacy_protocol::{self, SpanMode}, version, }; @@ -67,7 +66,7 @@ impl ProcMacroServerProcess { { &[ ( - Some("postcard-new"), + Some("bidirectional-postcard-prototype"), Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }, ), (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), @@ -92,7 +91,7 @@ impl ProcMacroServerProcess { }; let mut srv = create_srv()?; tracing::info!("sending proc-macro server version check"); - match srv.version_check() { + match srv.version_check(Some(&mut reject_subrequests)) { Ok(v) if v > version::CURRENT_API_VERSION => { #[allow(clippy::disallowed_methods)] let process_version = Command::new(process_path) @@ -110,7 +109,8 @@ impl ProcMacroServerProcess { tracing::info!("Proc-macro server version: {v}"); srv.version = v; if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT - && let Ok(new_mode) = srv.enable_rust_analyzer_spans() + && let Ok(new_mode) = + srv.enable_rust_analyzer_spans(Some(&mut reject_subrequests)) { match &mut srv.protocol { Protocol::LegacyJson { mode } @@ -156,25 +156,30 @@ impl ProcMacroServerProcess { } /// Checks the API version of the running proc-macro server. - fn version_check(&self) -> Result<u32, ServerError> { + fn version_check(&self, callback: Option<SubCallback<'_>>) -> Result<u32, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::version_check(self) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::version_check(self) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::version_check(self, cb) } } } /// Enable support for rust-analyzer span mode if the server supports it. - fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> { + fn enable_rust_analyzer_spans( + &self, + callback: Option<SubCallback<'_>>, + ) -> Result<SpanMode, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::enable_rust_analyzer_spans(self) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::enable_rust_analyzer_spans(self) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::enable_rust_analyzer_spans(self, cb) } } } @@ -183,20 +188,21 @@ impl ProcMacroServerProcess { pub(crate) fn find_proc_macros( &self, dylib_path: &AbsPath, + callback: Option<SubCallback<'_>>, ) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::find_proc_macros(self, dylib_path) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::find_proc_macros(self, dylib_path) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::find_proc_macros(self, dylib_path, cb) } } } pub(crate) fn expand( &self, - db: &dyn SourceDatabase, proc_macro: &ProcMacro, subtree: tt::SubtreeView<'_, Span>, attr: Option<tt::SubtreeView<'_, Span>>, @@ -205,12 +211,12 @@ impl ProcMacroServerProcess { call_site: Span, mixed_site: Span, current_dir: String, + callback: Option<SubCallback<'_>>, ) -> Result<Result<tt::TopSubtree<Span>, String>, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::expand( proc_macro, - db, subtree, attr, env, @@ -222,7 +228,6 @@ impl ProcMacroServerProcess { } Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( proc_macro, - db, subtree, attr, env, @@ -230,6 +235,7 @@ impl ProcMacroServerProcess { call_site, mixed_site, current_dir, + callback.expect("callback required for bidirectional protocol"), ), } } @@ -297,10 +303,10 @@ impl ProcMacroServerProcess { pub(crate) fn run_bidirectional<C: Codec>( &self, initial: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result<BidirectionalMessage, ServerError> { self.with_locked_io::<C, _>(|writer, reader, buf| { - bidirectional_protocol::run_conversation::<C>(writer, reader, buf, initial, callbacks) + bidirectional_protocol::run_conversation::<C>(writer, reader, buf, initial, callback) }) } } diff --git a/crates/proc-macro-srv-cli/src/main.rs b/crates/proc-macro-srv-cli/src/main.rs index 7e50888114..d73d20b584 100644 --- a/crates/proc-macro-srv-cli/src/main.rs +++ b/crates/proc-macro-srv-cli/src/main.rs @@ -57,7 +57,11 @@ enum ProtocolFormat { impl ValueEnum for ProtocolFormat { fn value_variants<'a>() -> &'a [Self] { - &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, ProtocolFormat::BidirectionalPostcardPrototype] + &[ + ProtocolFormat::JsonLegacy, + ProtocolFormat::PostcardLegacy, + ProtocolFormat::BidirectionalPostcardPrototype, + ] } fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> { @@ -66,14 +70,18 @@ impl ValueEnum for ProtocolFormat { ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) } - ProtocolFormat::BidirectionalPostcardPrototype => Some(clap::builder::PossibleValue::new("postcard-new")), + ProtocolFormat::BidirectionalPostcardPrototype => { + Some(clap::builder::PossibleValue::new("postcard-new")) + } } } fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> { match input { "json-legacy" => Ok(ProtocolFormat::JsonLegacy), "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), - "bidirectional-postcard-prototype" => Ok(ProtocolFormat::BidirectionalPostcardPrototype), + "bidirectional-postcard-prototype" => { + Ok(ProtocolFormat::BidirectionalPostcardPrototype) + } _ => Err(format!("unknown protocol format: {input}")), } } |