Skip to content

Commit e77a71f

Browse files
committed
Bring back usage tracking for settings-cleanup
1 parent 55cd32b commit e77a71f

File tree

5 files changed

+115
-15
lines changed

5 files changed

+115
-15
lines changed

binding-generator/src/bin/settings-cleanup.rs

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use std::cell::RefCell;
2-
use std::collections::HashSet;
2+
use std::collections::{HashMap, HashSet};
33
use std::ops::ControlFlow;
44
use std::path::{Path, PathBuf};
5+
use std::rc::Rc;
56
use std::{env, fmt};
67

78
use clang::{Entity, EntityKind};
89
use opencv_binding_generator::{
9-
opencv_module_from_path, settings, Class, EntityExt, EntityWalkerExt, EntityWalkerVisitor, Func, Generator, GeneratorEnv,
10+
opencv_module_from_path, settings, Class, Constness, EntityExt, EntityWalkerExt, EntityWalkerVisitor, Func, Generator,
11+
GeneratorEnv, Pred,
1012
};
1113

1214
struct FunctionFinder<'tu, 'f> {
@@ -18,14 +20,22 @@ struct FunctionFinder<'tu, 'f> {
1820

1921
impl<'tu, 'f> FunctionFinder<'tu, 'f> {
2022
pub fn update_used_func(&self, f: &Func) {
23+
let mut matcher = f.matcher();
24+
self.gen_env.settings.arg_override.get(&mut matcher);
25+
self.gen_env.settings.return_override.get(&mut matcher);
26+
self.gen_env.settings.force_infallible.get(&mut matcher);
27+
self.gen_env.settings.func_replace.get(&mut matcher);
28+
self.gen_env.settings.func_specialize.get(&mut matcher);
29+
self.gen_env.settings.func_unsafe.get(&mut matcher);
30+
2131
let identifier = f.identifier();
2232

2333
self.func_exclude_unused.borrow_mut().remove(identifier.as_str());
2434
self.func_cfg_attr_unused.borrow_mut().remove(identifier.as_str());
2535
}
2636
}
2737

28-
impl<'tu> EntityWalkerVisitor<'tu> for FunctionFinder<'tu, '_> {
38+
impl<'tu> EntityWalkerVisitor<'tu> for &mut FunctionFinder<'tu, '_> {
2939
fn wants_file(&mut self, path: &Path) -> bool {
3040
opencv_module_from_path(path).map_or(false, |m| m == self.module)
3141
}
@@ -78,6 +88,11 @@ fn main() {
7888
let opencv_header_dirs = args.map(PathBuf::from);
7989
let mut func_exclude_unused = settings::FUNC_EXCLUDE.clone();
8090
let mut func_cfg_attr_unused = settings::FUNC_CFG_ATTR.keys().copied().collect::<HashSet<_>>();
91+
// module -> usage_section -> (name, preds)
92+
let global_usage_tracking = Rc::new(RefCell::new(HashMap::<
93+
String,
94+
HashMap<&'static str, HashSet<UsageTrackerOwned>>,
95+
>::new()));
8196
for opencv_header_dir in opencv_header_dirs {
8297
println!("Processing header dir: {}", opencv_header_dir.display());
8398
let modules = opencv_header_dir
@@ -93,19 +108,84 @@ fn main() {
93108
let gen = Generator::new(&opencv_header_dir, &[], &src_cpp_dir);
94109
for module in modules {
95110
println!(" {module}");
96-
gen.pre_process(&module, false, |root_entity| {
97-
let gen_env = GeneratorEnv::global(&module, root_entity);
98-
root_entity.walk_opencv_entities(FunctionFinder {
99-
module: &module,
100-
gen_env,
101-
func_exclude_unused: RefCell::new(&mut func_exclude_unused),
102-
func_cfg_attr_unused: RefCell::new(&mut func_cfg_attr_unused),
103-
});
111+
gen.pre_process(&module, false, {
112+
let global_usage_tracking = Rc::clone(&global_usage_tracking);
113+
|root_entity| {
114+
let global_usage_tracking = global_usage_tracking; // force move
115+
let mut gen_env = GeneratorEnv::global(&module, root_entity);
116+
gen_env.settings.start_usage_tracking();
117+
let mut function_finder = FunctionFinder {
118+
module: &module,
119+
gen_env,
120+
func_exclude_unused: RefCell::new(&mut func_exclude_unused),
121+
func_cfg_attr_unused: RefCell::new(&mut func_cfg_attr_unused),
122+
};
123+
root_entity.walk_opencv_entities(&mut function_finder);
124+
125+
let usage_tracking = function_finder.gen_env.settings.finish_usage_tracking();
126+
let mut global_usage_tracking = global_usage_tracking.borrow_mut();
127+
let module_usage_tracking = global_usage_tracking.entry(module.to_string()).or_default();
128+
for (usage_section, new_usage_tracking) in usage_tracking {
129+
let new_usage_tracking: HashSet<UsageTrackerOwned> = new_usage_tracking
130+
.into_iter()
131+
.map(|(name, preds)| (name.to_string(), preds.iter().map(PredOwned::from_pred).collect()))
132+
.collect();
133+
if let Some(prev_usage_tracking) = module_usage_tracking.get_mut(usage_section) {
134+
*prev_usage_tracking = new_usage_tracking.intersection(prev_usage_tracking).cloned().collect();
135+
} else {
136+
module_usage_tracking.insert(usage_section, new_usage_tracking);
137+
}
138+
}
139+
}
104140
});
105141
}
106142
}
143+
144+
let global_usage_tracking = Rc::try_unwrap(global_usage_tracking).expect("Not owned").into_inner();
145+
let mut usage_per_section = HashMap::new();
146+
for (_module, module_usage) in global_usage_tracking {
147+
for (section, preds) in module_usage {
148+
let section_usage = usage_per_section.entry(section).or_insert_with(Vec::new);
149+
for (name, preds) in preds {
150+
section_usage.push((name, preds));
151+
}
152+
}
153+
}
154+
for (section, mut usage_tracking) in usage_per_section {
155+
if usage_tracking.is_empty() {
156+
println!("No unused entries in {section}");
157+
} else {
158+
println!("Unused entries in {section} ({}):", usage_tracking.len());
159+
usage_tracking.sort_unstable();
160+
for (name, mut preds) in usage_tracking {
161+
preds.sort_unstable();
162+
println!(" {name}: {preds:?}");
163+
}
164+
}
165+
}
107166
println!("Unused entries in settings::FUNC_EXCLUDE ({}):", func_exclude_unused.len());
108167
show(func_exclude_unused);
109168
println!("Unused entries in settings::FUNC_CFG_ATTR ({}):", func_cfg_attr_unused.len());
110169
show(func_cfg_attr_unused);
111170
}
171+
172+
type UsageTrackerOwned = (String, Vec<PredOwned>);
173+
174+
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
175+
enum PredOwned {
176+
Constness(Constness),
177+
Return(String),
178+
ArgNames(Vec<String>),
179+
ArgTypes(Vec<String>),
180+
}
181+
182+
impl PredOwned {
183+
fn from_pred(pred: &Pred) -> Self {
184+
match pred {
185+
Pred::Constness(c) => Self::Constness(*c),
186+
Pred::Return(r) => Self::Return(r.to_string()),
187+
Pred::ArgNames(a) => Self::ArgNames(a.iter().map(|s| s.to_string()).collect()),
188+
Pred::ArgTypes(a) => Self::ArgTypes(a.iter().map(|s| s.to_string()).collect()),
189+
}
190+
}
191+
}

binding-generator/src/func.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::rc::Rc;
66

77
use clang::{Availability, Entity, EntityKind, ExceptionSpecification};
88
pub use desc::{FuncCppBody, FuncDesc, FuncRustBody, FuncRustExtern};
9-
pub use func_matcher::{FuncMatchProperties, FuncMatcher, Pred};
9+
pub use func_matcher::{FuncMatchProperties, FuncMatcher, Pred, UsageTracker};
1010
pub use kind::{FuncKind, OperatorKind, ReturnKind};
1111
use once_cell::sync::Lazy;
1212
use regex::bytes::Regex;

binding-generator/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use tuple::Tuple;
4141
#[allow(unused)]
4242
use type_ref::dbg_clang_type;
4343
use type_ref::TypeRef;
44-
pub use type_ref::{CppNameStyle, NameStyle};
44+
pub use type_ref::{Constness, CppNameStyle, NameStyle};
4545
pub use typedef::Typedef;
4646
use vector::Vector;
4747
pub use walker::{EntityWalkerExt, EntityWalkerVisitor};

binding-generator/src/settings.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub use implemented::{
6464
use once_cell::sync::Lazy;
6565
pub use property_tweaks::{property_tweaks_factory, PropertyReadWrite, PropertyTweak, PropertyTweaks};
6666

67-
use crate::func::FuncMatcher;
67+
use crate::func::{FuncMatcher, UsageTracker};
6868
use crate::type_ref::TypeRef;
6969

7070
mod argument_names;
@@ -133,6 +133,26 @@ impl Settings {
133133
property_tweaks: property_tweaks_factory(module),
134134
}
135135
}
136+
137+
pub fn start_usage_tracking(&mut self) {
138+
self.arg_override.start_usage_tracking();
139+
self.return_override.start_usage_tracking();
140+
self.force_infallible.start_usage_tracking();
141+
self.func_replace.start_usage_tracking();
142+
self.func_specialize.start_usage_tracking();
143+
self.func_unsafe.start_usage_tracking();
144+
}
145+
146+
pub fn finish_usage_tracking(&mut self) -> HashMap<&'static str, HashSet<UsageTracker>> {
147+
HashMap::from([
148+
("ARG_OVERRIDE", self.arg_override.finish_usage_tracking()),
149+
("RETURN_OVERRIDE", self.return_override.finish_usage_tracking()),
150+
("FORCE_INFALLIBLE", self.force_infallible.finish_usage_tracking()),
151+
("FUNC_REPLACE", self.func_replace.finish_usage_tracking()),
152+
("FUNC_SPECIALIZE", self.func_specialize.finish_usage_tracking()),
153+
("FUNC_UNSAFE", self.func_unsafe.finish_usage_tracking()),
154+
])
155+
}
136156
}
137157

138158
// fixme, generalize, make it use constant::ValueKind

binding-generator/src/type_ref/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ pub enum ExternDir {
289289
FromCpp,
290290
}
291291

292-
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
292+
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
293293
pub enum Constness {
294294
Const,
295295
Mut,

0 commit comments

Comments
 (0)