Implement more reliable function id
MODIFY
binding-generator/src/bin/settings-cleanup.rs
binding-generator/src/bin/settings-cleanup.rs
@@ -26,7 +26,7 @@ struct FunctionFinder<'tu, 'f> {
pub func_unsafe_unused: &'f mut HashSet<&'static str>,
pub func_manual_unused: &'f mut HashSet<&'static str>,
pub func_specialize_unused: &'f mut HashSet<&'static str>,
- pub slice_argument_unused: &'f mut HashSet<&'static str>, // fixme, doesn't seem to work perfectly (shows cv::mixChannels, but it's def used)
+ pub slice_argument_unused: &'f mut HashSet<String>, // fixme, doesn't seem to work perfectly (shows cv::mixChannels, but it's def used)
}
impl<'tu, 'f> FunctionFinder<'tu, 'f> {
@@ -116,8 +116,8 @@ fn main() {
let mut func_unsafe_unused = settings::FUNC_UNSAFE.clone();
let mut func_manual_unused = settings::FUNC_MANUAL.keys().copied().collect::<HashSet<_>>();
let mut func_specialize_unused = settings::FUNC_SPECIALIZE.keys().copied().collect::<HashSet<_>>();
- let mut slice_argument_unused = settings::SLICE_ARGUMENT.keys().copied()
- .map(|(cpp_fullname, _)| cpp_fullname)
+ let mut slice_argument_unused = settings::SLICE_ARGUMENT.keys().cloned()
+ .map(|func_id| func_id.name().to_string())
.collect::<HashSet<_>>();
for opencv_header_dir in opencv_header_dirs {
println!("Processing header dir: {}", opencv_header_dir.display());

MODIFY
binding-generator/src/func.rs
binding-generator/src/func.rs
use std::{
+ array::IntoIter,
borrow::Cow,
collections::HashMap,
fmt,
@@ -91,6 +92,56 @@ pub enum FunctionTypeHint {
Specialized(&'static HashMap<&'static str, &'static str>),
}
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+pub struct FuncId<'f> {
+ name: Cow<'f, str>,
+ args: Vec<Cow<'f, str>>,
+}
+
+impl<'f> FuncId<'f> {
+ /// # Parameters
+ /// name: fully qualified C++ function name (e.g. cv::Mat::create)
+ /// args: C++ argument names ("unnamed", "unnamed_1", ... for unnamed ones)
+ pub fn new<const ARGS: usize>(name: &'static str, args: [&'static str; ARGS]) -> FuncId<'static> {
+ FuncId {
+ name: name.into(),
+ args: IntoIter::new(args).map(|a| a.into()).collect(),
+ }
+ }
+
+ pub fn from_entity(entity: Entity) -> Self {
+ let name = entity.cpp_fullname().into_owned().into();
+ let args = if let EntityKind::FunctionTemplate = entity.get_kind() {
+ let mut args = vec![];
+ entity.walk_children_while(|child| {
+ if child.get_kind() == EntityKind::ParmDecl {
+ args.push(child.get_name()
+ .map(Cow::Owned)
+ .unwrap_or_else(|| "unnamed".into()));
+ }
+ true
+ });
+ args
+ } else {
+ entity.get_arguments().into_iter()
+ .flatten()
+ .map(|a| a.get_name()
+ .map(Cow::Owned)
+ .unwrap_or_else(|| "unnamed".into()))
+ .collect()
+ };
+ Self { name, args }
+ }
+
+ pub fn name(&self) -> &str {
+ self.name.as_ref()
+ }
+
+ pub fn args(&self) -> &[Cow<str>] {
+ &self.args
+ }
+}
+
#[derive(Clone)]
pub struct Func<'tu, 'ge> {
entity: Entity<'tu>,
@@ -376,10 +427,8 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
} else {
&empty_hashmap
};
- let args_len = args.len();
- let func_name = self.cpp_fullname();
let is_field_setter = self.as_field_setter().is_some();
- let slice_args = settings::SLICE_ARGUMENT.get(&(func_name.as_ref(), args_len));
+ let slice_args = settings::SLICE_ARGUMENT.get(&self.func_id());
args.into_iter()
.map(|a| {
@@ -461,6 +510,10 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
}
out.into()
}
+
+ pub fn func_id(&self) -> FuncId {
+ FuncId::from_entity(self.entity)
+ }
}
impl<'tu> EntityElement<'tu> for Func<'tu, '_> {

MODIFY
binding-generator/src/settings.rs
binding-generator/src/settings.rs
@@ -6,7 +6,7 @@ use std::collections::{BTreeSet, HashMap, HashSet};
use maplit::{btreeset, hashmap, hashset};
use once_cell::sync::Lazy;
-use crate::{CompiledInterpolation, ExportConfig, StrExt};
+use crate::{CompiledInterpolation, ExportConfig, func::FuncId, StrExt};
/// map of functions to rename or skip, key is Func.identifier(), value is new name ("+" will be replaced by old name) or "-" to skip
pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| hashmap! {
@@ -881,60 +881,65 @@ pub enum SliceHint {
}
/// (cpp_fullname, argument count)
-pub static SLICE_ARGUMENT: Lazy<HashMap<(&str, usize), HashMap<&str, SliceHint>>> = Lazy::new(|| hashmap! {
- ("cv::Mat::at", 1) => hashmap! {
+pub static SLICE_ARGUMENT: Lazy<HashMap<FuncId, HashMap<&str, SliceHint>>> = Lazy::new(|| hashmap! {
+ FuncId::new("cv::Mat::at", ["idx"]) => hashmap! {
"idx" => SliceHint::Slice
},
- ("cv::Mat::ptr", 1) => hashmap! {
+ FuncId::new("cv::Mat::ptr", ["idx"]) => hashmap! {
"idx" => SliceHint::Slice
},
- ("cv::Mat::Mat", 4) => hashmap! {
+ FuncId::new("cv::Mat::Mat", ["sizes", "type", "data", "steps"]) => hashmap! {
"steps" => SliceHint::NullableSlice,
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::Mat::Mat", 5) => hashmap! {
+ FuncId::new("cv::Mat::Mat", ["ndims", "sizes", "type", "s"]) => hashmap! {
"steps" => SliceHint::NullableSlice,
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::Mat::zeros", 3) => hashmap! {
+ FuncId::new("cv::Mat::Mat", ["ndims", "sizes", "type", "data", "steps"]) => hashmap! {
+ "steps" => SliceHint::NullableSlice,
+ "sizes" => SliceHint::Slice,
+ "ndims" => SliceHint::LenForSlice("sizes", 1),
+ },
+ FuncId::new("cv::Mat::zeros", ["ndims", "sz", "type"]) => hashmap! {
"sz" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sz", 1),
},
- ("cv::Mat::ones", 3) => hashmap! {
+ FuncId::new("cv::Mat::ones", ["ndims", "sz", "type"]) => hashmap! {
"sz" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sz", 1),
},
- ("cv::Mat::create", 3) => hashmap! {
+ FuncId::new("cv::Mat::create", ["ndims", "sizes", "type"]) => hashmap! {
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::Mat::reshape", 3) => hashmap! {
+ FuncId::new("cv::Mat::reshape", ["cn", "newndims", "newsz"]) => hashmap! {
"newsz" => SliceHint::Slice,
"newndims" => SliceHint::LenForSlice("newsz", 1),
},
- ("cv::SparseMat::Hdr::Hdr", 3) => hashmap! {
+ FuncId::new("cv::SparseMat::Hdr::Hdr", ["_dims", "_sizes", "_type"]) => hashmap! {
"_sizes" => SliceHint::Slice,
"_dims" => SliceHint::LenForSlice("_sizes", 1),
},
- ("cv::UMat::UMat", 4) => hashmap! {
+ FuncId::new("cv::UMat::UMat", ["ndims", "sizes", "type", "usageFlags"]) => hashmap! {
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::UMat::UMat", 5) => hashmap! {
+ FuncId::new("cv::UMat::UMat", ["ndims", "sizes", "type", "s", "usageFlags"]) => hashmap! {
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::UMat::create", 4) => hashmap! {
+ FuncId::new("cv::UMat::create", ["ndims", "sizes", "type", "usageFlags"]) => hashmap! {
"sizes" => SliceHint::Slice,
"ndims" => SliceHint::LenForSlice("sizes", 1),
},
- ("cv::_OutputArray::create", 6) => hashmap! {
+ FuncId::new("cv::_OutputArray::create", ["dims", "size", "type", "i", "allowTransposed", "fixedDepthMask"]) => hashmap! {
"size" => SliceHint::Slice,
"dims" => SliceHint::LenForSlice("size", 1),
},
- ("cv::mixChannels", 4) => hashmap! {
+ FuncId::new("cv::mixChannels", ["src", "dst", "fromTo", "npairs"]) => hashmap! {
"from_to" => SliceHint::Slice,
"npairs" => SliceHint::LenForSlice("from_to", 2),
},

Implement more reliable function id