mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Implement ra_proc_macro client logic
This commit is contained in:
parent
fa3c7742af
commit
503cbd3f4b
11 changed files with 827 additions and 23 deletions
|
@ -5,55 +5,102 @@
|
|||
//! is used to provide basic infrastructure for communication between two
|
||||
//! processes: Client (RA itself), Server (the external program)
|
||||
|
||||
mod rpc;
|
||||
mod process;
|
||||
pub mod msg;
|
||||
|
||||
use process::ProcMacroProcessSrv;
|
||||
use ra_tt::{SmolStr, Subtree};
|
||||
use rpc::ProcMacroKind;
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub use rpc::{ExpansionResult, ExpansionTask};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProcMacroProcessExpander {
|
||||
process: Arc<ProcMacroProcessSrv>,
|
||||
dylib_path: PathBuf,
|
||||
name: SmolStr,
|
||||
}
|
||||
|
||||
impl Eq for ProcMacroProcessExpander {}
|
||||
impl PartialEq for ProcMacroProcessExpander {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
&& self.dylib_path == other.dylib_path
|
||||
&& Arc::ptr_eq(&self.process, &other.process)
|
||||
}
|
||||
}
|
||||
|
||||
impl ra_tt::TokenExpander for ProcMacroProcessExpander {
|
||||
fn expand(
|
||||
&self,
|
||||
_subtree: &Subtree,
|
||||
subtree: &Subtree,
|
||||
_attr: Option<&Subtree>,
|
||||
) -> Result<Subtree, ra_tt::ExpansionError> {
|
||||
// FIXME: do nothing for now
|
||||
Ok(Subtree::default())
|
||||
self.process.custom_derive(&self.dylib_path, subtree, &self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ProcMacroProcessSrv {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ProcMacroClient {
|
||||
#[derive(Debug, Clone)]
|
||||
enum ProcMacroClientKind {
|
||||
Process { process: Arc<ProcMacroProcessSrv> },
|
||||
Dummy,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProcMacroClient {
|
||||
kind: ProcMacroClientKind,
|
||||
}
|
||||
|
||||
impl ProcMacroClient {
|
||||
pub fn extern_process(process_path: &Path) -> ProcMacroClient {
|
||||
let process = ProcMacroProcessSrv { path: process_path.into() };
|
||||
ProcMacroClient::Process { process: Arc::new(process) }
|
||||
pub fn extern_process(process_path: &Path) -> Result<ProcMacroClient, std::io::Error> {
|
||||
let process = ProcMacroProcessSrv::run(process_path)?;
|
||||
Ok(ProcMacroClient { kind: ProcMacroClientKind::Process { process: Arc::new(process) } })
|
||||
}
|
||||
|
||||
pub fn dummy() -> ProcMacroClient {
|
||||
ProcMacroClient::Dummy
|
||||
ProcMacroClient { kind: ProcMacroClientKind::Dummy }
|
||||
}
|
||||
|
||||
pub fn by_dylib_path(
|
||||
&self,
|
||||
_dylib_path: &Path,
|
||||
dylib_path: &Path,
|
||||
) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> {
|
||||
// FIXME: return empty for now
|
||||
vec![]
|
||||
match &self.kind {
|
||||
ProcMacroClientKind::Dummy => vec![],
|
||||
ProcMacroClientKind::Process { process } => {
|
||||
let macros = match process.find_proc_macros(dylib_path) {
|
||||
Err(err) => {
|
||||
eprintln!("Fail to find proc macro. Error: {:#?}", err);
|
||||
return vec![];
|
||||
}
|
||||
Ok(macros) => macros,
|
||||
};
|
||||
|
||||
macros
|
||||
.into_iter()
|
||||
.filter_map(|(name, kind)| {
|
||||
// FIXME: Support custom derive only for now.
|
||||
match kind {
|
||||
ProcMacroKind::CustomDerive => {
|
||||
let name = SmolStr::new(&name);
|
||||
let expander: Arc<dyn ra_tt::TokenExpander> =
|
||||
Arc::new(ProcMacroProcessExpander {
|
||||
process: process.clone(),
|
||||
name: name.clone(),
|
||||
dylib_path: dylib_path.into(),
|
||||
});
|
||||
Some((name, expander))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue