internal: remove unreasonable crate dependency

Proc macro expansion shouldn't know about salsa at all.
This commit is contained in:
Aleksey Kladov 2021-08-22 14:05:12 +03:00
parent 881d71a489
commit e86388689f
6 changed files with 71 additions and 38 deletions

1
Cargo.lock generated
View file

@ -1120,7 +1120,6 @@ dependencies = [
name = "proc_macro_api" name = "proc_macro_api"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"base_db",
"crossbeam-channel", "crossbeam-channel",
"jod-thread", "jod-thread",
"log", "log",

View file

@ -15,17 +15,16 @@ log = "0.4.8"
crossbeam-channel = "0.5.0" crossbeam-channel = "0.5.0"
jod-thread = "0.1.1" jod-thread = "0.1.1"
memmap2 = "0.3.0" memmap2 = "0.3.0"
object = { version = "0.26", default-features = false, features = [
"std",
"read_core",
"elf",
"macho",
"pe",
] }
snap = "1.0" snap = "1.0"
paths = { path = "../paths", version = "0.0.0" } paths = { path = "../paths", version = "0.0.0" }
tt = { path = "../tt", version = "0.0.0" } tt = { path = "../tt", version = "0.0.0" }
base_db = { path = "../base_db", version = "0.0.0" }
stdx = { path = "../stdx", version = "0.0.0" } stdx = { path = "../stdx", version = "0.0.0" }
profile = { path = "../profile", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" }
# Intentionally *not* depend on anything salsa-related
# base_db = { path = "../base_db", version = "0.0.0" }
[dependencies.object]
version = "0.26"
default-features = false
features = [ "std", "read_core", "elf", "macho", "pe" ]

View file

@ -10,7 +10,6 @@ mod process;
mod rpc; mod rpc;
mod version; mod version;
use base_db::{Env, ProcMacro};
use paths::{AbsPath, AbsPathBuf}; use paths::{AbsPath, AbsPathBuf};
use std::{ use std::{
ffi::OsStr, ffi::OsStr,
@ -26,34 +25,44 @@ pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask,
pub use version::{read_dylib_info, RustCInfo}; pub use version::{read_dylib_info, RustCInfo};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct ProcMacroProcessExpander { pub struct ProcMacroProcessExpander {
process: Arc<Mutex<ProcMacroProcessSrv>>, process: Arc<Mutex<ProcMacroProcessSrv>>,
dylib_path: AbsPathBuf, dylib_path: AbsPathBuf,
name: SmolStr, name: SmolStr,
kind: ProcMacroKind,
} }
impl Eq for ProcMacroProcessExpander {} impl Eq for ProcMacroProcessExpander {}
impl PartialEq for ProcMacroProcessExpander { impl PartialEq for ProcMacroProcessExpander {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.name == other.name self.name == other.name
&& self.kind == other.kind
&& self.dylib_path == other.dylib_path && self.dylib_path == other.dylib_path
&& Arc::ptr_eq(&self.process, &other.process) && Arc::ptr_eq(&self.process, &other.process)
} }
} }
impl base_db::ProcMacroExpander for ProcMacroProcessExpander { impl ProcMacroProcessExpander {
fn expand( pub fn name(&self) -> &str {
&self.name
}
pub fn kind(&self) -> ProcMacroKind {
self.kind
}
pub fn expand(
&self, &self,
subtree: &Subtree, subtree: &Subtree,
attr: Option<&Subtree>, attr: Option<&Subtree>,
env: &Env, env: Vec<(String, String)>,
) -> Result<Subtree, tt::ExpansionError> { ) -> Result<Subtree, tt::ExpansionError> {
let task = ExpansionTask { let task = ExpansionTask {
macro_body: subtree.clone(), macro_body: subtree.clone(),
macro_name: self.name.to_string(), macro_name: self.name.to_string(),
attributes: attr.cloned(), attributes: attr.cloned(),
lib: self.dylib_path.to_path_buf(), lib: self.dylib_path.to_path_buf(),
env: env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(), env,
}; };
let result: ExpansionResult = self let result: ExpansionResult = self
@ -86,7 +95,7 @@ impl ProcMacroClient {
Ok(ProcMacroClient { process: Arc::new(Mutex::new(process)) }) Ok(ProcMacroClient { process: Arc::new(Mutex::new(process)) })
} }
pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec<ProcMacro> { pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec<ProcMacroProcessExpander> {
let _p = profile::span("ProcMacroClient::by_dylib_path"); let _p = profile::span("ProcMacroClient::by_dylib_path");
match version::read_dylib_info(dylib_path) { match version::read_dylib_info(dylib_path) {
Ok(info) => { Ok(info) => {
@ -118,20 +127,11 @@ impl ProcMacroClient {
macros macros
.into_iter() .into_iter()
.map(|(name, kind)| { .map(|(name, kind)| ProcMacroProcessExpander {
let name = SmolStr::new(&name); process: self.process.clone(),
let kind = match kind { name: name.into(),
ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, kind,
ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, dylib_path: dylib_path.to_path_buf(),
ProcMacroKind::Attr => base_db::ProcMacroKind::Attr,
};
let expander = Arc::new(ProcMacroProcessExpander {
process: self.process.clone(),
name: name.clone(),
dylib_path: dylib_path.to_path_buf(),
});
ProcMacro { name, kind, expander }
}) })
.collect() .collect()
} }

View file

@ -52,6 +52,7 @@ vfs = { path = "../vfs", version = "0.0.0" }
vfs-notify = { path = "../vfs-notify", version = "0.0.0" } vfs-notify = { path = "../vfs-notify", version = "0.0.0" }
cfg = { path = "../cfg", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" }
toolchain = { path = "../toolchain", version = "0.0.0" } toolchain = { path = "../toolchain", version = "0.0.0" }
tt = { path = "../tt", version = "0.0.0" }
proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
# This should only be used in CLI # This should only be used in CLI

View file

@ -11,7 +11,7 @@ use proc_macro_api::ProcMacroClient;
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, WorkspaceBuildScripts}; use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, WorkspaceBuildScripts};
use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use vfs::{loader::Handle, AbsPath, AbsPathBuf};
use crate::reload::{ProjectFolders, SourceRootConfig}; use crate::reload::{load_proc_macro, ProjectFolders, SourceRootConfig};
// Note: Since this type is used by external tools that use rust-analyzer as a library // Note: Since this type is used by external tools that use rust-analyzer as a library
// what otherwise would be `pub(crate)` has to be `pub` here instead. // what otherwise would be `pub(crate)` has to be `pub` here instead.
@ -69,9 +69,7 @@ pub fn load_workspace(
}); });
let crate_graph = ws.to_crate_graph( let crate_graph = ws.to_crate_graph(
&mut |path: &AbsPath| { &mut |path: &AbsPath| load_proc_macro(proc_macro_client.as_ref(), path),
proc_macro_client.as_ref().map(|it| it.by_dylib_path(path)).unwrap_or_default()
},
&mut |path: &AbsPath| { &mut |path: &AbsPath| {
let contents = loader.load_sync(path); let contents = loader.load_sync(path);
let path = vfs::VfsPath::from(path.to_path_buf()); let path = vfs::VfsPath::from(path.to_path_buf());

View file

@ -4,7 +4,9 @@ use std::{mem, sync::Arc};
use flycheck::{FlycheckConfig, FlycheckHandle}; use flycheck::{FlycheckConfig, FlycheckHandle};
use hir::db::DefDatabase; use hir::db::DefDatabase;
use ide::Change; use ide::Change;
use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; use ide_db::base_db::{
CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroKind, SourceRoot, VfsPath,
};
use proc_macro_api::ProcMacroClient; use proc_macro_api::ProcMacroClient;
use project_model::{ProjectWorkspace, WorkspaceBuildScripts}; use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
@ -398,9 +400,8 @@ impl GlobalState {
// Create crate graph from all the workspaces // Create crate graph from all the workspaces
let crate_graph = { let crate_graph = {
let proc_macro_client = self.proc_macro_client.as_ref(); let proc_macro_client = self.proc_macro_client.as_ref();
let mut load_proc_macro = move |path: &AbsPath| { let mut load_proc_macro =
proc_macro_client.map(|it| it.by_dylib_path(path)).unwrap_or_default() move |path: &AbsPath| load_proc_macro(proc_macro_client, path);
};
let vfs = &mut self.vfs.write().0; let vfs = &mut self.vfs.write().0;
let loader = &mut self.loader; let loader = &mut self.loader;
@ -587,3 +588,38 @@ impl SourceRootConfig {
.collect() .collect()
} }
} }
pub(crate) fn load_proc_macro(client: Option<&ProcMacroClient>, path: &AbsPath) -> Vec<ProcMacro> {
return client
.map(|it| it.by_dylib_path(path))
.unwrap_or_default()
.into_iter()
.map(expander_to_proc_macro)
.collect();
fn expander_to_proc_macro(expander: proc_macro_api::ProcMacroProcessExpander) -> ProcMacro {
let name = expander.name().into();
let kind = match expander.kind() {
proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive,
proc_macro_api::ProcMacroKind::FuncLike => ProcMacroKind::FuncLike,
proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr,
};
let expander = Arc::new(Expander(expander));
ProcMacro { name, kind, expander }
}
#[derive(Debug)]
struct Expander(proc_macro_api::ProcMacroProcessExpander);
impl ProcMacroExpander for Expander {
fn expand(
&self,
subtree: &tt::Subtree,
attrs: Option<&tt::Subtree>,
env: &Env,
) -> Result<tt::Subtree, tt::ExpansionError> {
let env = env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect();
self.0.expand(subtree, attrs, env)
}
}
}