mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
feat: Add config to replace specific proc-macros with dummy expanders
This commit is contained in:
parent
68bc12c3b8
commit
aecf26d09b
6 changed files with 68 additions and 17 deletions
|
@ -55,6 +55,8 @@ pub trait InternDatabase: SourceDatabase {
|
||||||
pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
|
pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
|
||||||
#[salsa::input]
|
#[salsa::input]
|
||||||
fn enable_proc_attr_macros(&self) -> bool;
|
fn enable_proc_attr_macros(&self) -> bool;
|
||||||
|
#[salsa::input]
|
||||||
|
fn enablse_proc_attr_macros(&self) -> bool;
|
||||||
|
|
||||||
#[salsa::invoke(ItemTree::file_item_tree_query)]
|
#[salsa::invoke(ItemTree::file_item_tree_query)]
|
||||||
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
|
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
|
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
|
||||||
project_workspace.to_crate_graph(&mut |_| Vec::new(), &mut {
|
project_workspace.to_crate_graph(&Default::default(), &mut |_, _| Vec::new(), &mut {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
move |_path| {
|
move |_path| {
|
||||||
counter += 1;
|
counter += 1;
|
||||||
|
|
|
@ -387,10 +387,14 @@ impl ProjectWorkspace {
|
||||||
|
|
||||||
pub fn to_crate_graph(
|
pub fn to_crate_graph(
|
||||||
&self,
|
&self,
|
||||||
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
|
dummy_replace: &FxHashMap<Box<str>, Box<[Box<str>]>>,
|
||||||
|
load_proc_macro: &mut dyn FnMut(&AbsPath, &[Box<str>]) -> Vec<ProcMacro>,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
) -> CrateGraph {
|
) -> CrateGraph {
|
||||||
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
||||||
|
let load_proc_macro = &mut |crate_name: &_, path: &_| {
|
||||||
|
load_proc_macro(path, dummy_replace.get(crate_name).map(|it| &**it).unwrap_or_default())
|
||||||
|
};
|
||||||
|
|
||||||
let mut crate_graph = match self {
|
let mut crate_graph = match self {
|
||||||
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
|
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
|
||||||
|
@ -432,7 +436,7 @@ impl ProjectWorkspace {
|
||||||
|
|
||||||
fn project_json_to_crate_graph(
|
fn project_json_to_crate_graph(
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
|
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
project: &ProjectJson,
|
project: &ProjectJson,
|
||||||
sysroot: &Option<Sysroot>,
|
sysroot: &Option<Sysroot>,
|
||||||
|
@ -452,7 +456,12 @@ fn project_json_to_crate_graph(
|
||||||
})
|
})
|
||||||
.map(|(crate_id, krate, file_id)| {
|
.map(|(crate_id, krate, file_id)| {
|
||||||
let env = krate.env.clone().into_iter().collect();
|
let env = krate.env.clone().into_iter().collect();
|
||||||
let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| load_proc_macro(&it));
|
let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| {
|
||||||
|
load_proc_macro(
|
||||||
|
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
|
||||||
|
&it,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let target_cfgs = match krate.target.as_deref() {
|
let target_cfgs = match krate.target.as_deref() {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
|
@ -513,7 +522,7 @@ fn project_json_to_crate_graph(
|
||||||
fn cargo_to_crate_graph(
|
fn cargo_to_crate_graph(
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
override_cfg: &CfgOverrides,
|
override_cfg: &CfgOverrides,
|
||||||
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
|
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
cargo: &CargoWorkspace,
|
cargo: &CargoWorkspace,
|
||||||
build_scripts: &WorkspaceBuildScripts,
|
build_scripts: &WorkspaceBuildScripts,
|
||||||
|
@ -571,7 +580,7 @@ fn cargo_to_crate_graph(
|
||||||
&cargo[pkg],
|
&cargo[pkg],
|
||||||
build_scripts.outputs.get(pkg),
|
build_scripts.outputs.get(pkg),
|
||||||
cfg_options,
|
cfg_options,
|
||||||
load_proc_macro,
|
&mut |path| load_proc_macro(&cargo[tgt].name, path),
|
||||||
file_id,
|
file_id,
|
||||||
&cargo[tgt].name,
|
&cargo[tgt].name,
|
||||||
);
|
);
|
||||||
|
@ -702,7 +711,7 @@ fn handle_rustc_crates(
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
cfg_options: &CfgOptions,
|
cfg_options: &CfgOptions,
|
||||||
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
|
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
|
||||||
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
|
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
|
||||||
public_deps: &SysrootPublicDeps,
|
public_deps: &SysrootPublicDeps,
|
||||||
cargo: &CargoWorkspace,
|
cargo: &CargoWorkspace,
|
||||||
|
@ -738,7 +747,7 @@ fn handle_rustc_crates(
|
||||||
&rustc_workspace[pkg],
|
&rustc_workspace[pkg],
|
||||||
None,
|
None,
|
||||||
cfg_options,
|
cfg_options,
|
||||||
load_proc_macro,
|
&mut |path| load_proc_macro(&rustc_workspace[tgt].name, path),
|
||||||
file_id,
|
file_id,
|
||||||
&rustc_workspace[tgt].name,
|
&rustc_workspace[tgt].name,
|
||||||
);
|
);
|
||||||
|
|
|
@ -66,7 +66,8 @@ pub fn load_workspace(
|
||||||
};
|
};
|
||||||
|
|
||||||
let crate_graph = ws.to_crate_graph(
|
let crate_graph = ws.to_crate_graph(
|
||||||
&mut |path: &AbsPath| load_proc_macro(proc_macro_client.as_ref(), path),
|
&Default::default(),
|
||||||
|
&mut |path: &AbsPath, _| load_proc_macro(proc_macro_client.as_ref(), path, &[]),
|
||||||
&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());
|
||||||
|
|
|
@ -301,6 +301,7 @@ config_data! {
|
||||||
/// Internal config, path to proc-macro server executable (typically,
|
/// Internal config, path to proc-macro server executable (typically,
|
||||||
/// this is rust-analyzer itself, but we override this in tests).
|
/// this is rust-analyzer itself, but we override this in tests).
|
||||||
procMacro_server: Option<PathBuf> = "null",
|
procMacro_server: Option<PathBuf> = "null",
|
||||||
|
procMacro_dummies: FxHashMap<Box<str>, Box<[Box<str>]>> = "{}",
|
||||||
|
|
||||||
/// Command to be executed instead of 'cargo' for runnables.
|
/// Command to be executed instead of 'cargo' for runnables.
|
||||||
runnables_overrideCargo: Option<String> = "null",
|
runnables_overrideCargo: Option<String> = "null",
|
||||||
|
@ -716,6 +717,9 @@ impl Config {
|
||||||
};
|
};
|
||||||
Some((path, vec!["proc-macro".into()]))
|
Some((path, vec!["proc-macro".into()]))
|
||||||
}
|
}
|
||||||
|
pub fn dummy_replacements(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
|
||||||
|
&self.data.procMacro_dummies
|
||||||
|
}
|
||||||
pub fn expand_proc_attr_macros(&self) -> bool {
|
pub fn expand_proc_attr_macros(&self) -> bool {
|
||||||
self.data.experimental_procAttrMacros
|
self.data.experimental_procAttrMacros
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use ide_db::base_db::{
|
||||||
};
|
};
|
||||||
use proc_macro_api::{MacroDylib, ProcMacroServer};
|
use proc_macro_api::{MacroDylib, ProcMacroServer};
|
||||||
use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
|
use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
|
||||||
|
use syntax::SmolStr;
|
||||||
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
|
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -290,6 +291,9 @@ impl GlobalState {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
self.analysis_host
|
||||||
|
.raw_database_mut()
|
||||||
|
.set_enable_proc_attr_macros(self.config.expand_proc_attr_macros());
|
||||||
}
|
}
|
||||||
|
|
||||||
let watch = match files_config.watcher {
|
let watch = match files_config.watcher {
|
||||||
|
@ -306,8 +310,9 @@ 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 =
|
let mut load_proc_macro = move |path: &AbsPath, dummy_replace: &_| {
|
||||||
move |path: &AbsPath| load_proc_macro(proc_macro_client, path);
|
load_proc_macro(proc_macro_client, path, dummy_replace)
|
||||||
|
};
|
||||||
|
|
||||||
let vfs = &mut self.vfs.write().0;
|
let vfs = &mut self.vfs.write().0;
|
||||||
let loader = &mut self.loader;
|
let loader = &mut self.loader;
|
||||||
|
@ -328,7 +333,11 @@ impl GlobalState {
|
||||||
|
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
for ws in self.workspaces.iter() {
|
for ws in self.workspaces.iter() {
|
||||||
crate_graph.extend(ws.to_crate_graph(&mut load_proc_macro, &mut load));
|
crate_graph.extend(ws.to_crate_graph(
|
||||||
|
self.config.dummy_replacements(),
|
||||||
|
&mut load_proc_macro,
|
||||||
|
&mut load,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
crate_graph
|
crate_graph
|
||||||
};
|
};
|
||||||
|
@ -505,7 +514,11 @@ impl SourceRootConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) -> Vec<ProcMacro> {
|
pub(crate) fn load_proc_macro(
|
||||||
|
client: Option<&ProcMacroServer>,
|
||||||
|
path: &AbsPath,
|
||||||
|
dummy_replace: &[Box<str>],
|
||||||
|
) -> Vec<ProcMacro> {
|
||||||
let dylib = match MacroDylib::new(path.to_path_buf()) {
|
let dylib = match MacroDylib::new(path.to_path_buf()) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -532,17 +545,25 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath)
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(expander_to_proc_macro)
|
.map(|expander| expander_to_proc_macro(expander, dummy_replace))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
fn expander_to_proc_macro(expander: proc_macro_api::ProcMacro) -> ProcMacro {
|
fn expander_to_proc_macro(
|
||||||
let name = expander.name().into();
|
expander: proc_macro_api::ProcMacro,
|
||||||
|
dummy_replace: &[Box<str>],
|
||||||
|
) -> ProcMacro {
|
||||||
|
let name = SmolStr::from(expander.name());
|
||||||
let kind = match expander.kind() {
|
let kind = match expander.kind() {
|
||||||
proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive,
|
proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive,
|
||||||
proc_macro_api::ProcMacroKind::FuncLike => ProcMacroKind::FuncLike,
|
proc_macro_api::ProcMacroKind::FuncLike => ProcMacroKind::FuncLike,
|
||||||
proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr,
|
proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr,
|
||||||
};
|
};
|
||||||
let expander = Arc::new(Expander(expander));
|
let expander: Arc<dyn ProcMacroExpander> =
|
||||||
|
if dummy_replace.iter().any(|replace| &**replace == name) {
|
||||||
|
Arc::new(DummyExpander)
|
||||||
|
} else {
|
||||||
|
Arc::new(Expander(expander))
|
||||||
|
};
|
||||||
ProcMacro { name, kind, expander }
|
ProcMacro { name, kind, expander }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +585,20 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct DummyExpander;
|
||||||
|
|
||||||
|
impl ProcMacroExpander for DummyExpander {
|
||||||
|
fn expand(
|
||||||
|
&self,
|
||||||
|
subtree: &tt::Subtree,
|
||||||
|
_: Option<&tt::Subtree>,
|
||||||
|
_: &Env,
|
||||||
|
) -> Result<tt::Subtree, ProcMacroExpansionError> {
|
||||||
|
Ok(subtree.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool {
|
pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool {
|
||||||
|
|
Loading…
Reference in a new issue