-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: Add config to replace specific proc-macros with dummy expanders #11193
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ use ide_db::base_db::{ | |
}; | ||
use proc_macro_api::{MacroDylib, ProcMacroServer}; | ||
use project_model::{ProjectWorkspace, WorkspaceBuildScripts}; | ||
use syntax::SmolStr; | ||
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; | ||
|
||
use crate::{ | ||
|
@@ -306,8 +307,9 @@ impl GlobalState { | |
// Create crate graph from all the workspaces | ||
let crate_graph = { | ||
let proc_macro_client = self.proc_macro_client.as_ref(); | ||
let mut load_proc_macro = | ||
move |path: &AbsPath| load_proc_macro(proc_macro_client, path); | ||
let mut load_proc_macro = move |path: &AbsPath, dummy_replace: &_| { | ||
load_proc_macro(proc_macro_client, path, dummy_replace) | ||
}; | ||
|
||
let vfs = &mut self.vfs.write().0; | ||
let loader = &mut self.loader; | ||
|
@@ -328,7 +330,11 @@ impl GlobalState { | |
|
||
let mut crate_graph = CrateGraph::default(); | ||
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 | ||
}; | ||
|
@@ -505,7 +511,13 @@ impl SourceRootConfig { | |
} | ||
} | ||
|
||
pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) -> Vec<ProcMacro> { | ||
/// Load the proc-macros for the given lib path, replacing all expanders whose names are in `dummy_replace` | ||
/// with an identity dummy expander. | ||
pub(crate) fn load_proc_macro( | ||
client: Option<&ProcMacroServer>, | ||
path: &AbsPath, | ||
dummy_replace: &[Box<str>], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if perhaps we should implement this on the higher level and treat such macros as inert attributes? ah, I see you’ve considered that. I wonder if we can treat this as a custom tool attribute (#[rustfmt and such) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tool attribute would be nice in theory, but since those are unstable and therefor require a feature flag I am doubtful that people would even bother using it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean, we presumably have some infrastruture internally to track tool/intert attributes and say things like " Basically, make |
||
) -> Vec<ProcMacro> { | ||
let dylib = match MacroDylib::new(path.to_path_buf()) { | ||
Ok(it) => it, | ||
Err(err) => { | ||
|
@@ -532,17 +544,25 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) | |
Vec::new() | ||
} | ||
}) | ||
.map(expander_to_proc_macro) | ||
.map(|expander| expander_to_proc_macro(expander, dummy_replace)) | ||
.collect(); | ||
|
||
fn expander_to_proc_macro(expander: proc_macro_api::ProcMacro) -> ProcMacro { | ||
let name = expander.name().into(); | ||
fn expander_to_proc_macro( | ||
expander: proc_macro_api::ProcMacro, | ||
dummy_replace: &[Box<str>], | ||
) -> ProcMacro { | ||
let name = SmolStr::from(expander.name()); | ||
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)); | ||
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 } | ||
} | ||
|
||
|
@@ -564,6 +584,21 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) | |
} | ||
} | ||
} | ||
|
||
/// Dummy identity expander, used for proc-macros that are deliberately ignored by the user. | ||
#[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 { | ||
|
Uh oh!
There was an error while loading. Please reload this page.