Unnamed repository; edit this file 'description' to name the repository.
remove internal callbacks, and move callback to rust-analyzer level
bit-aloo 4 months ago
parent 2c71fa8 · commit 336f025
-rw-r--r--.github/workflows/ci.yaml5
-rw-r--r--Cargo.lock1
-rw-r--r--crates/load-cargo/src/lib.rs22
-rw-r--r--crates/proc-macro-api/Cargo.toml1
-rw-r--r--crates/proc-macro-api/src/bidirectional_protocol.rs85
-rw-r--r--crates/proc-macro-api/src/legacy_protocol.rs2
-rw-r--r--crates/proc-macro-api/src/lib.rs15
-rw-r--r--crates/proc-macro-api/src/process.rs36
-rw-r--r--crates/proc-macro-srv-cli/src/main.rs14
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}")),
}
}