Skip to content

[Draft] feat: new protocol for proc-macro-api #19978

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/proc-macro-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ rust-version.workspace = true
[dependencies]
serde.workspace = true
serde_derive.workspace = true
postcard = { version = "1.1.1", features = ["alloc"] }
serde_json = { workspace = true, features = ["unbounded_depth"] }
tracing.workspace = true
rustc-hash.workspace = true
Expand All @@ -24,7 +25,7 @@ paths = { workspace = true, features = ["serde1"] }
tt.workspace = true
stdx.workspace = true
# span = {workspace = true, default-features = false} does not work
span = { path = "../span", version = "0.0.0", default-features = false}
span = { path = "../span", version = "0.0.0", default-features = false }

intern.workspace = true

Expand Down
10 changes: 10 additions & 0 deletions crates/proc-macro-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ pub mod legacy_protocol {
pub mod json;
pub mod msg;
}

#[allow(dead_code)]
pub mod new_protocol {
pub mod msg;
pub mod proto;
}

#[allow(dead_code)]
pub mod task;

mod process;

use paths::{AbsPath, AbsPathBuf};
Expand Down
158 changes: 158 additions & 0 deletions crates/proc-macro-api/src/new_protocol/msg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
//! New Protocol Message Definitions covers the functionalities of `legacy_protocol` and with several changes:
//!
//! - Using [postcard](https://github.com/jamesmunns/postcard) as serde library, which provides binary, lightweight serialization.
//! - As we change to postcard, no need to use FlatTree, use `tt::TopSubtree` directly
//!
//! One possible communication may look like this:
//! client ------------------------- server
//! >-------Request--------->
//! <-------Query-----------<
//! >-------Reply----------->
//! <-------Response-------<

use paths::Utf8PathBuf;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::ProcMacroKind;
use crate::legacy_protocol::msg::FlatTree;

/// Represents messages send from client to proc-macr-srv
#[derive(Debug, Serialize, Deserialize)]
pub enum C2SMsg {
Request(Request),
// NOTE: Reply is left empty as a placeholder
Reply,
}

/// Represents messages send from client to proc-macr-srv
#[derive(Debug, Serialize, Deserialize)]
pub enum S2CMsg {
Response(Response),
// NOTE: Query is left empty as a place holder
Query,
}

// NOTE: Directly copied from legacy_protocol
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
ListMacros { dylib_path: Utf8PathBuf },
ExpandMacro(Box<ExpandMacro>),
ApiVersionCheck {},
SetConfig(ServerConfig),
}

// NOTE: Directly copied from legacy_protocol
#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
ExpandMacro(Result<TreeWrapper, PanicMessage>),
ApiVersionCheck(u32),
SetConfig(ServerConfig),
ExpandMacroExtended(Result<ExpandMacroExtended, PanicMessage>),
}

// NOTE: Directly copied from legacy_protocol
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct ServerConfig {
pub span_mode: SpanMode,
}

// NOTE: Directly copied from legacy_protocol,
// except the tree field
#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacroExtended {
/// The expanded syntax tree.
pub tree: TreeWrapper,
/// Additional span data mappings.
pub span_data_table: Vec<u32>,
}

// NOTE: Directly copied from legacy_protocol
#[derive(Debug, Serialize, Deserialize)]
pub struct PanicMessage(pub String);

// NOTE: Directly copied from legacy_protocol
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub enum SpanMode {
#[default]
Id,
RustAnalyzer,
}

// NOTE: Directly copied from legacy_protocol
#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacro {
pub lib: Utf8PathBuf,

pub env: Vec<(String, String)>,

pub current_dir: Option<String>,

#[serde(flatten)]
pub data: ExpandMacroData,
}

// TODO: Maybe ideal we want to ser/de TokenTree directly
//
// Something like this should be ideal
// pub struct TreeWrapper<S>(tt::TokenTree<S>);
// currently, just use this wrapper to build the backbones
#[derive(Debug)]
pub struct TreeWrapper(FlatTree);

// TODO: How to serialize/deserialize TokenTree?
// Seems impossible to derive all the underlying wrapped types to serialize/deserialize, which will change tons of code
//
impl Serialize for TreeWrapper {
fn serialize<Ser>(&self, _serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: Serializer,
{
todo!("Implement Serialize for TreeWrapper<S> if needed")
}
}

impl<'de> Deserialize<'de> for TreeWrapper {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
todo!("Implement Deserialize for TreeWrapper<S> if needed")
}
}

// NOTE: Directly copied from legacy_protocol,
// except the tree field
#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacroData {
pub macro_body: TreeWrapper,

pub macro_name: String,

pub attributes: Option<TreeWrapper>,
#[serde(skip_serializing_if = "ExpnGlobals::skip_serializing_if")]
#[serde(default)]
pub has_global_spans: ExpnGlobals,

#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub span_data_table: Vec<u32>,
}

// NOTE: Directly copied from legacy_protocol,
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub struct ExpnGlobals {
#[serde(skip_serializing)]
#[serde(default)]
pub serialize: bool,
pub def_site: usize,
pub call_site: usize,
pub mixed_site: usize,
}

impl ExpnGlobals {
fn skip_serializing_if(&self) -> bool {
!self.serialize
}
}
Loading
Loading