Skip to content

Commit

Permalink
Deglobalize FUNC_SPECIALIZE
Browse files Browse the repository at this point in the history
  • Loading branch information
twistedfall committed Oct 14, 2024
1 parent c81a20c commit 8f0d4a9
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 127 deletions.
9 changes: 0 additions & 9 deletions binding-generator/src/bin/settings-cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ struct FunctionFinder<'tu, 'f> {
pub func_cfg_attr_unused: RefCell<&'f mut HashSet<&'static str>>,
pub func_unsafe_unused: RefCell<&'f mut HashSet<FuncId<'static>>>,
pub func_replace_unused: RefCell<&'f mut HashSet<FuncId<'static>>>,
pub func_specialize_unused: RefCell<&'f mut HashSet<FuncId<'static>>>,
pub argument_override_unused: RefCell<&'f mut HashSet<FuncId<'static>>>,
}

Expand All @@ -32,7 +31,6 @@ impl<'tu, 'f> FunctionFinder<'tu, 'f> {
self.func_cfg_attr_unused.borrow_mut().remove(identifier.as_str());
self.func_unsafe_unused.borrow_mut().remove(&func_id);
self.func_replace_unused.borrow_mut().remove(&func_id);
self.func_specialize_unused.borrow_mut().remove(&func_id);
self.argument_override_unused.borrow_mut().remove(&func_id);
}
}
Expand Down Expand Up @@ -93,7 +91,6 @@ fn main() {
let mut func_cfg_attr_unused = settings::FUNC_CFG_ATTR.keys().copied().collect::<HashSet<_>>();
let mut func_unsafe_unused = settings::FUNC_UNSAFE.clone();
let mut func_replace_unused = settings::FUNC_REPLACE.keys().cloned().collect::<HashSet<_>>();
let mut func_specialize_unused = settings::FUNC_SPECIALIZE.keys().cloned().collect::<HashSet<_>>();
let mut argument_override_unused = settings::ARGUMENT_OVERRIDE.keys().cloned().collect::<HashSet<_>>();
for opencv_header_dir in opencv_header_dirs {
println!("Processing header dir: {}", opencv_header_dir.display());
Expand All @@ -120,7 +117,6 @@ fn main() {
func_cfg_attr_unused: RefCell::new(&mut func_cfg_attr_unused),
func_unsafe_unused: RefCell::new(&mut func_unsafe_unused),
func_replace_unused: RefCell::new(&mut func_replace_unused),
func_specialize_unused: RefCell::new(&mut func_specialize_unused),
argument_override_unused: RefCell::new(&mut argument_override_unused),
});
});
Expand All @@ -136,11 +132,6 @@ fn main() {
show(func_unsafe_unused);
println!("Unused entries in settings::FUNC_REPLACE ({}):", func_replace_unused.len());
show(func_replace_unused);
println!(
"Unused entries in settings::FUNC_SPECIALIZE ({}):",
func_specialize_unused.len()
);
show(func_specialize_unused);
println!(
"Unused entries in settings::ARGUMENT_OVERRIDE ({}):",
argument_override_unused.len()
Expand Down
12 changes: 7 additions & 5 deletions binding-generator/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,14 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
} else {
func
};
if func.is_generic() {
if let Some(specs) = settings::FUNC_SPECIALIZE.get(&func.func_id()) {
for spec in specs {
out.push(func.clone().specialize(spec));
if let Self::Clang { gen_env, .. } = self {
if func.is_generic() {
if let Some(specs) = gen_env.settings.func_specialize.get(&func.func_id()) {
for spec in specs {
out.push(func.clone().specialize(spec));
}
return ControlFlow::Continue(());
}
return ControlFlow::Continue(());
}
}
out.push(func);
Expand Down
19 changes: 12 additions & 7 deletions binding-generator/src/func.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::borrow::Cow::{Borrowed, Owned};
use std::collections::HashMap;
use std::fmt;
use std::ops::ControlFlow;
use std::rc::Rc;
Expand All @@ -18,8 +17,8 @@ use crate::debug::{DefinitionLocation, LocationName};
use crate::element::ExcludeKind;
use crate::entity::ToEntity;
use crate::field::FieldDesc;
use crate::settings::{TypeRefFactory, ARG_OVERRIDE_SELF};
use crate::type_ref::{Constness, CppNameStyle, TypeRefDesc, TypeRefTypeHint};
use crate::settings::{FuncSpec, ARG_OVERRIDE_SELF};
use crate::type_ref::{Constness, CppNameStyle, FishStyle, TypeRefDesc, TypeRefTypeHint};
use crate::writer::rust_native::element::RustElement;
use crate::writer::rust_native::type_ref::TypeRefExt;
use crate::{
Expand Down Expand Up @@ -87,10 +86,11 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
}
}

pub fn specialize(self, spec: &HashMap<&str, TypeRefFactory>) -> Self {
pub fn specialize(self, spec: &FuncSpec) -> Self {
let specialized = |type_ref: &TypeRef| -> Option<TypeRef<'static, 'static>> {
if type_ref.kind().is_generic() {
spec
.1
.get(type_ref.source().cpp_name(CppNameStyle::Declaration).as_ref())
.map(|spec_type| type_ref.map(|_| spec_type().with_inherent_constness(type_ref.constness())))
} else {
Expand Down Expand Up @@ -121,16 +121,21 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
FuncKind::GenericInstanceMethod(cls) => FuncKind::InstanceMethod(cls),
kind => kind,
};
let spec_values = spec.values();
let spec_values = spec.1.values();
let mut generic = String::with_capacity(spec_values.len() * 16);
for spec in spec_values {
let spec = spec();
generic.extend_sep(", ", &spec.cpp_name(CppNameStyle::Reference));
generic.extend_sep(", ", &spec().cpp_name(CppNameStyle::Reference));
}
let mut desc = self.to_desc(InheritConfig::empty().kind().arguments().return_type_ref());
let rust_custom_leafname = Some(if spec.0.contains('+') {
spec.0.replacen('+', &self.rust_leafname(FishStyle::No), 1).into()
} else {
spec.0.into()
});
let desc_mut = Rc::make_mut(&mut desc);
desc_mut.kind = kind;
desc_mut.type_hint = FuncTypeHint::Specialized;
desc_mut.rust_custom_leafname = rust_custom_leafname;
desc_mut.arguments = arguments;
desc_mut.return_type_ref = specialized(&return_type_ref).unwrap_or_else(|| return_type_ref.into_owned());
desc_mut.cpp_body = FuncCppBody::ManualCall(format!("{{{{name}}}}<{generic}>({{{{args}}}})").into());
Expand Down
48 changes: 20 additions & 28 deletions binding-generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use clang::{Clang, Entity, EntityKind, Index};
use dunce::canonicalize;
use shlex::Shlex;

use crate::name_pool::NamePool;
use crate::type_ref::{CppNameStyle, FishStyle, TypeRef, TypeRefKind};
use crate::typedef::NewTypedefResult;
use crate::writer::rust_native::element::RustElement;
Expand Down Expand Up @@ -81,6 +82,7 @@ pub struct OpenCvWalker<'tu, 'r, V> {
module: &'r str,
opencv_module_header_dir: &'r Path,
visitor: V,
func_names: NamePool,
gen_env: GeneratorEnv<'tu>,
}

Expand Down Expand Up @@ -135,10 +137,8 @@ impl<'tu, V: GeneratorVisitor<'tu>> EntityWalkerVisitor<'tu> for OpenCvWalker<'t
| EntityKind::ClassTemplatePartialSpecialization
| EntityKind::StructDecl => Self::process_class(&mut self.visitor, &mut self.gen_env, entity),
EntityKind::EnumDecl => Self::process_enum(&mut self.visitor, entity),
EntityKind::FunctionDecl => Self::process_func(&mut self.visitor, &mut self.gen_env, entity),
EntityKind::TypedefDecl | EntityKind::TypeAliasDecl => {
Self::process_typedef(&mut self.visitor, &mut self.gen_env, entity)
}
EntityKind::FunctionDecl => Self::process_func(&mut self.visitor, &mut self.func_names, &self.gen_env, entity),
EntityKind::TypedefDecl | EntityKind::TypeAliasDecl => Self::process_typedef(&mut self.visitor, &self.gen_env, entity),
EntityKind::VarDecl => {
if !entity.is_mutable() {
Self::process_const(&mut self.visitor, entity);
Expand Down Expand Up @@ -210,6 +210,7 @@ impl<'tu, 'r, V: GeneratorVisitor<'tu>> OpenCvWalker<'tu, 'r, V> {
module,
opencv_module_header_dir,
visitor,
func_names: NamePool::with_capacity(512),
gen_env,
}
}
Expand Down Expand Up @@ -271,51 +272,42 @@ impl<'tu, 'r, V: GeneratorVisitor<'tu>> OpenCvWalker<'tu, 'r, V> {
}
}

fn process_func(visitor: &mut V, gen_env: &mut GeneratorEnv<'tu>, func_decl: Entity<'tu>) {
fn process_func(visitor: &mut V, func_names: &mut NamePool, gen_env: &GeneratorEnv<'tu>, func_decl: Entity<'tu>) {
if let Some(e) = gen_env.get_export_config(func_decl) {
let func = Func::new(func_decl, gen_env);
let func = if let Some(func_fact) = settings::FUNC_REPLACE.get(&func.func_id()) {
let func_id = func.func_id();
let func: Func = if let Some(func_fact) = settings::FUNC_REPLACE.get(&func_id) {
func_fact(&func)
} else {
func
Func::new(func_decl, gen_env)
};
if func.exclude_kind().is_included() {
let func_id = func.func_id().make_static();
let mut processor = |spec| {
let func = if e.only_generated_types {
Func::new(func_decl, gen_env)
} else {
let mut name = Func::new(func_decl, gen_env).rust_leafname(FishStyle::No).into_owned().into();
let mut rust_custom_leafname = None;
if gen_env.func_names.make_unique_name(&mut name).is_changed() {
rust_custom_leafname = Some(name.into());
}
Func::new_ext(func_decl, rust_custom_leafname, gen_env)
};
let func = if let Some(spec) = spec {
func.specialize(spec)
} else {
func
};
let mut processor = |mut func: Func<'tu, '_>| {
func.generated_types().into_iter().for_each(|dep| {
visitor.visit_generated_type(dep);
});
if !e.only_generated_types {
let mut name = func.rust_leafname(FishStyle::No).into_owned().into();
let mut rust_custom_leafname = None;
if func_names.make_unique_name(&mut name).is_changed() {
rust_custom_leafname = Some(name.into());
}
func.set_rust_custom_leafname(rust_custom_leafname);
visitor.visit_func(func);
}
};
if let Some(specs) = settings::FUNC_SPECIALIZE.get(&func_id) {
if let Some(specs) = gen_env.settings.func_specialize.get(&func_id) {
for spec in specs {
processor(Some(spec));
processor(func.clone().specialize(spec));
}
} else {
processor(None);
processor(func);
}
}
}
}

fn process_typedef(visitor: &mut V, gen_env: &mut GeneratorEnv<'tu>, typedef_decl: Entity<'tu>) {
fn process_typedef(visitor: &mut V, gen_env: &GeneratorEnv<'tu>, typedef_decl: Entity<'tu>) {
let typedef = Typedef::try_new(typedef_decl, gen_env);
if typedef.exclude_kind().is_included() {
match typedef {
Expand Down
6 changes: 1 addition & 5 deletions binding-generator/src/generator_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::settings::Settings;
use crate::type_ref::CppNameStyle;
use crate::{
is_opencv_path, opencv_module_from_path, settings, Class, Element, EntityWalkerExt, EntityWalkerVisitor, MemoizeMap,
MemoizeMapExt, NamePool,
MemoizeMapExt,
};

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -173,7 +173,6 @@ impl<'tu> EntityWalkerVisitor<'tu> for GeneratorEnvPopulator<'tu, '_> {
pub struct GeneratorEnv<'tu> {
export_map: HashMap<ExportIdx, ExportConfig>,
rename_map: HashMap<ExportIdx, RenameConfig>,
pub func_names: NamePool,
/// Collection of function comments to be able to replace `@overload` and `@copybrief` comment markers
func_comments: HashMap<String, Vec<(u32, String)>>,
/// Cache of the calculated [ClassKind]s
Expand All @@ -187,7 +186,6 @@ impl<'tu> GeneratorEnv<'tu> {
Self {
export_map: HashMap::new(),
rename_map: HashMap::new(),
func_names: NamePool::with_capacity(0),
func_comments: HashMap::new(),
class_kind_cache: MemoizeMap::new(HashMap::new()),
descendants: HashMap::new(),
Expand All @@ -200,7 +198,6 @@ impl<'tu> GeneratorEnv<'tu> {
let mut out = Self {
export_map: HashMap::with_capacity(1024),
rename_map: HashMap::with_capacity(64),
func_names: NamePool::with_capacity(512),
func_comments: HashMap::with_capacity(2048),
class_kind_cache: MemoizeMap::new(HashMap::with_capacity(32)),
descendants: HashMap::with_capacity(16),
Expand Down Expand Up @@ -366,7 +363,6 @@ impl fmt::Debug for GeneratorEnv<'_> {
f.debug_struct("GeneratorEnv")
.field("export_map", &format!("{} elements", self.export_map.len()))
.field("rename_map", &format!("{} elements", self.rename_map.len()))
.field("func_names", &format!("{} elements", self.func_names.len()))
.field("func_comments", &format!("{} elements", self.func_comments.len()))
.field(
"class_kind_cache",
Expand Down
4 changes: 0 additions & 4 deletions binding-generator/src/name_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ impl NamePool {
}
}

pub fn len(&self) -> usize {
self.names.len()
}

pub fn make_unique_name(&mut self, name: &mut Cow<str>) -> MakeUniqueNameResult {
let mut out = MakeUniqueNameResult::Unchanged;
while self.names.contains(name.as_ref()) {
Expand Down
13 changes: 10 additions & 3 deletions binding-generator/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pub use element_export_tweak::ELEMENT_EXPORT_TWEAK;
pub use force_infallible::FORCE_INFALLIBLE;
pub use func_cfg_attr::FUNC_CFG_ATTR;
pub use func_exclude::FUNC_EXCLUDE;
pub use func_inject::{func_inject_factory, FuncFactory};
pub use func_inject::{func_inject_factory, FuncFactory, FuncInject};
pub use func_rename::FUNC_RENAME;
pub use func_replace::{FuncInheritFactory, FUNC_REPLACE};
pub use func_specialize::{TypeRefFactory, FUNC_SPECIALIZE};
pub use func_specialize::{func_specialize_factory, FuncSpec, FuncSpecialize};
pub use func_unsafe::FUNC_UNSAFE;
pub use generator_module_tweaks::{generator_module_tweaks_factory, ModuleTweak};
pub use implemented::{
Expand All @@ -21,6 +21,8 @@ pub use implemented::{
};
use once_cell::sync::Lazy;

use crate::type_ref::TypeRef;

mod argument_names;
mod argument_override;
mod element_exclude_kind;
Expand All @@ -36,24 +38,29 @@ mod func_unsafe;
mod generator_module_tweaks;
mod implemented;

pub type TypeRefFactory = fn() -> TypeRef<'static, 'static>;

/// Injectable global and module level overrides, todo: migrate the global statics to this over time
#[derive(Debug)]
pub struct Settings {
pub func_inject: Vec<FuncFactory>,
pub func_inject: FuncInject,
pub func_specialize: FuncSpecialize,
pub generator_module_tweaks: ModuleTweak<'static>,
}

impl Settings {
pub fn empty() -> Self {
Self {
func_inject: vec![],
func_specialize: HashMap::new(),
generator_module_tweaks: ModuleTweak::empty(),
}
}

pub fn for_module(module: &str) -> Self {
Self {
func_inject: func_inject_factory(module),
func_specialize: func_specialize_factory(module),
generator_module_tweaks: generator_module_tweaks_factory(module),
}
}
Expand Down
4 changes: 3 additions & 1 deletion binding-generator/src/settings/func_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use crate::type_ref::{TypeRef, TypeRefDesc, TypeRefTypeHint};
use crate::writer::rust_native::type_ref::Lifetime;
use crate::Func;

pub type FuncInject = Vec<FuncFactory>;

pub type FuncFactory = fn() -> Func<'static, 'static>;

pub fn func_inject_factory(module: &str) -> Vec<FuncFactory> {
pub fn func_inject_factory(module: &str) -> FuncInject {
match module {
"core" => vec![
(|| {
Expand Down
17 changes: 0 additions & 17 deletions binding-generator/src/settings/func_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,6 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
("cv_AsyncArray_get_const_const__OutputArrayR_int64_t", "+_with_timeout"),
("cv_AsyncArray_wait_for_const_double", "+_f64"),
("cv_Cholesky_floatX_size_t_int_floatX_size_t_int", "+_f32"),
("cv_CommandLineParser_get_bool_const_const_StringR_bool", "+_bool"),
("cv_CommandLineParser_get_bool_const_int_bool", "+_bool_idx"),
("cv_CommandLineParser_get_cv_String_const_const_StringR_bool", "+_str"),
("cv_CommandLineParser_get_cv_String_const_int_bool", "+_str_idx"),
("cv_CommandLineParser_get_double_const_const_StringR_bool", "+_f64"),
("cv_CommandLineParser_get_double_const_int_bool", "+_f64_idx"),
("cv_CommandLineParser_get_int_const_const_StringR_bool", "+_i32"),
("cv_CommandLineParser_get_int_const_int_bool", "+_i32_idx"),
("cv_CommandLineParser_get_uint64_t_const_const_StringR_bool", "+_u64"),
("cv_CommandLineParser_get_uint64_t_const_int_bool", "+_u64_idx"),
("cv_DMatch_DMatch_int_int_int_float", "new_index"),
("cv_FileStorage_write_const_StringR_const_MatR", "+_mat"),
("cv_FileStorage_write_const_StringR_const_StringR", "+_str"),
Expand Down Expand Up @@ -333,14 +323,7 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
("cv_dnn_DictValue_DictValue_int", "from_i32"),
("cv_dnn_DictValue_DictValue_int64_t", "from_i64"),
("cv_dnn_DictValue_DictValue_unsigned_int", "from_u32"),
("cv_dnn_DictValue_get_cv_String_const_int", "+_str"),
("cv_dnn_DictValue_get_double_const_int", "+_f64"),
("cv_dnn_DictValue_get_int64_t_const_int", "+_i64"),
("cv_dnn_DictValue_get_int_const_int", "+_i32"),
("cv_dnn_Dict_ptr_const_StringR", "+_mut"),
("cv_dnn_Dict_set_const_cv_String_const_StringR_const_StringR", "+_str"),
("cv_dnn_Dict_set_const_double_const_StringR_const_doubleR", "+_f64"),
("cv_dnn_Dict_set_const_int64_t_const_StringR_const_int64_tR", "+_i64"),
("cv_dnn_Layer_finalize_const_vectorLMatGR", "+_mat"),
("cv_dnn_Layer_finalize_const_vectorLMatGR_vectorLMatGR", "+_mat_to"),
("cv_dnn_Layer_forward_vectorLMatXGR_vectorLMatGR_vectorLMatGR", "+_mat"),
Expand Down
Loading

0 comments on commit 8f0d4a9

Please sign in to comment.