mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Change macro stack monitor test to func ptr based
This commit is contained in:
parent
b177813f3b
commit
d6d9aa2003
1 changed files with 25 additions and 40 deletions
|
@ -42,25 +42,21 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
|
||||||
unresolved_imports: Vec::new(),
|
unresolved_imports: Vec::new(),
|
||||||
unexpanded_macros: Vec::new(),
|
unexpanded_macros: Vec::new(),
|
||||||
global_macro_scope: FxHashMap::default(),
|
global_macro_scope: FxHashMap::default(),
|
||||||
macro_stack_monitor: SimpleMacroStackMonitor::default(),
|
macro_stack_monitor: MacroStackMonitor::default(),
|
||||||
};
|
};
|
||||||
collector.collect();
|
collector.collect();
|
||||||
collector.finish()
|
collector.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MacroStackMonitor {
|
|
||||||
fn increase(&mut self, macro_def_id: MacroDefId);
|
|
||||||
fn decrease(&mut self, macro_def_id: MacroDefId);
|
|
||||||
|
|
||||||
fn is_poison(&self, macro_def_id: MacroDefId) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SimpleMacroStackMonitor {
|
struct MacroStackMonitor {
|
||||||
counts: FxHashMap<MacroDefId, u32>,
|
counts: FxHashMap<MacroDefId, u32>,
|
||||||
|
|
||||||
|
/// Mainly use for test
|
||||||
|
validator: Option<Box<dyn Fn(u32) -> bool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacroStackMonitor for SimpleMacroStackMonitor {
|
impl MacroStackMonitor {
|
||||||
fn increase(&mut self, macro_def_id: MacroDefId) {
|
fn increase(&mut self, macro_def_id: MacroDefId) {
|
||||||
*self.counts.entry(macro_def_id).or_default() += 1;
|
*self.counts.entry(macro_def_id).or_default() += 1;
|
||||||
}
|
}
|
||||||
|
@ -70,12 +66,18 @@ impl MacroStackMonitor for SimpleMacroStackMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_poison(&self, macro_def_id: MacroDefId) -> bool {
|
fn is_poison(&self, macro_def_id: MacroDefId) -> bool {
|
||||||
*self.counts.get(¯o_def_id).unwrap_or(&0) > 100
|
let cur = *self.counts.get(¯o_def_id).unwrap_or(&0);
|
||||||
|
|
||||||
|
if let Some(validator) = &self.validator {
|
||||||
|
validator(cur)
|
||||||
|
} else {
|
||||||
|
cur > 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks the tree of module recursively
|
/// Walks the tree of module recursively
|
||||||
struct DefCollector<DB, M> {
|
struct DefCollector<DB> {
|
||||||
db: DB,
|
db: DB,
|
||||||
def_map: CrateDefMap,
|
def_map: CrateDefMap,
|
||||||
glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
|
glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
|
||||||
|
@ -85,13 +87,12 @@ struct DefCollector<DB, M> {
|
||||||
|
|
||||||
/// Some macro use `$tt:tt which mean we have to handle the macro perfectly
|
/// Some macro use `$tt:tt which mean we have to handle the macro perfectly
|
||||||
/// To prevent stackoverflow, we add a deep counter here for prevent that.
|
/// To prevent stackoverflow, we add a deep counter here for prevent that.
|
||||||
macro_stack_monitor: M,
|
macro_stack_monitor: MacroStackMonitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, DB, M> DefCollector<&'a DB, M>
|
impl<'a, DB> DefCollector<&'a DB>
|
||||||
where
|
where
|
||||||
DB: DefDatabase,
|
DB: DefDatabase,
|
||||||
M: MacroStackMonitor,
|
|
||||||
{
|
{
|
||||||
fn collect(&mut self) {
|
fn collect(&mut self) {
|
||||||
let crate_graph = self.db.crate_graph();
|
let crate_graph = self.db.crate_graph();
|
||||||
|
@ -393,10 +394,9 @@ struct ModCollector<'a, D> {
|
||||||
raw_items: &'a raw::RawItems,
|
raw_items: &'a raw::RawItems,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DB, M> ModCollector<'_, &'_ mut DefCollector<&'_ DB, M>>
|
impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>>
|
||||||
where
|
where
|
||||||
DB: DefDatabase,
|
DB: DefDatabase,
|
||||||
M: MacroStackMonitor,
|
|
||||||
{
|
{
|
||||||
fn collect(&mut self, items: &[raw::RawItem]) {
|
fn collect(&mut self, items: &[raw::RawItem]) {
|
||||||
for item in items {
|
for item in items {
|
||||||
|
@ -578,31 +578,10 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
struct LimitedMacroStackMonitor {
|
|
||||||
count: u32,
|
|
||||||
limit: u32,
|
|
||||||
poison_limit: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MacroStackMonitor for LimitedMacroStackMonitor {
|
|
||||||
fn increase(&mut self, _: MacroDefId) {
|
|
||||||
self.count += 1;
|
|
||||||
assert!(self.count < self.limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decrease(&mut self, _: MacroDefId) {
|
|
||||||
self.count -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_poison(&self, _: MacroDefId) -> bool {
|
|
||||||
self.count >= self.poison_limit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_collect_defs(
|
fn do_collect_defs(
|
||||||
db: &impl DefDatabase,
|
db: &impl DefDatabase,
|
||||||
def_map: CrateDefMap,
|
def_map: CrateDefMap,
|
||||||
monitor: impl MacroStackMonitor,
|
monitor: MacroStackMonitor,
|
||||||
) -> CrateDefMap {
|
) -> CrateDefMap {
|
||||||
let mut collector = DefCollector {
|
let mut collector = DefCollector {
|
||||||
db,
|
db,
|
||||||
|
@ -639,7 +618,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
do_collect_defs(&db, def_map, LimitedMacroStackMonitor { count: 0, limit, poison_limit })
|
let mut monitor = MacroStackMonitor::default();
|
||||||
|
monitor.validator = Some(Box::new(move |count| {
|
||||||
|
assert!(count < limit);
|
||||||
|
count >= poison_limit
|
||||||
|
}));
|
||||||
|
|
||||||
|
do_collect_defs(&db, def_map, monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue