Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
twistedfall committed Jan 23, 2025
1 parent 6bf6fed commit c43f377
Show file tree
Hide file tree
Showing 35 changed files with 911 additions and 842 deletions.
6 changes: 2 additions & 4 deletions binding-generator/src/bin/settings-cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ impl<'tu> EntityWalkerVisitor<'tu> for &mut FunctionFinder<'tu> {
| EntityKind::StructDecl => {
let c = Class::new(entity, &self.gen_env);
if !c.template_kind().is_template() {
c.methods().into_iter().for_each(|f| self.update_used_func(&f));
let fields = c.fields();
c.field_methods(fields.iter(), None)
.into_iter()
c.methods(|_| true).into_iter().for_each(|f| self.update_used_func(&f));
c.field_methods(&c.fields(|_| true), None)
.for_each(|f| self.update_used_func(&f));
entity.walk_methods_while(|child| {
let func = Func::new(child, &self.gen_env);
Expand Down
66 changes: 42 additions & 24 deletions binding-generator/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
Self::Desc(Rc::new(desc))
}

/// Checks whether a class can be simple on Rust side, i.e. represented by plain struct with public fields
/// Checks whether a class can be simple on Rust side, i.e. represented by plain struct with fields
pub fn can_be_simple(&self) -> bool {
let cpp_refname = self.cpp_name(CppNameStyle::Reference);
settings::IMPLEMENTED_GENERICS.contains(cpp_refname.as_ref())
Expand Down Expand Up @@ -329,7 +329,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
}
}

pub fn methods(&self) -> Vec<Func<'tu, 'ge>> {
pub fn methods(&self, filter: impl Fn(&Func) -> bool) -> Vec<Func<'tu, 'ge>> {
match self {
Class::Clang { entity, gen_env, .. } => {
let mut out = Vec::with_capacity(32);
Expand All @@ -343,18 +343,23 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
if func.is_generic() {
if let Some(specs) = gen_env.settings.func_specialize.get(&mut func.matcher()) {
for spec in specs {
out.push(func.clone().specialize(spec));
let spec_func = func.clone().specialize(spec);
if filter(&spec_func) {
out.push(spec_func);
}
}
return ControlFlow::Continue(());
}
}
out.push(func);
if filter(&func) {
out.push(func);
}
ControlFlow::Continue(())
});
for inject_func_fact in &gen_env.settings.func_inject {
let inject_func: Func = inject_func_fact();
if let Some(cls) = inject_func.kind().as_class_method() {
if cls == self {
if cls == self && filter(&inject_func) {
out.push(inject_func);
}
}
Expand All @@ -377,10 +382,12 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
}
}

pub fn fields(&self) -> Vec<Field<'tu, 'ge>> {
pub fn fields(&self, filter: impl Fn(&Field) -> bool) -> Vec<Field<'tu, 'ge>> {
let mut out = Vec::with_capacity(32);
self.for_each_field(|f| {
out.push(f);
if filter(&f) {
out.push(f);
}
ControlFlow::Continue(())
});
out
Expand All @@ -405,16 +412,13 @@ impl<'tu, 'ge> Class<'tu, 'ge> {

pub fn field_methods<'f>(
&self,
fields: impl Iterator<Item = &'f Field<'tu, 'ge>>,
fields: &'f [Field<'tu, 'ge>],
constness_filter: Option<Constness>,
) -> Vec<Func<'tu, 'ge>>
where
'tu: 'f,
'ge: 'f,
{
) -> impl Iterator<Item = Func<'tu, 'ge>> + 'f {
match self {
&Self::Clang { gen_env, .. } => {
let accessor_generator = |fld: &Field<'tu, 'ge>| {
let cls = self.clone();
let accessor_generator = move |fld: &Field<'tu, 'ge>| {
let doc_comment = Rc::from(fld.doc_comment());
let def_loc = fld.file_line_name().location;
let rust_module = Rc::from(fld.rust_module());
Expand Down Expand Up @@ -449,7 +453,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
let read_const_func = if constness_filter.map_or(true, |c| c.is_const()) {
Some(Func::new_desc(
FuncDesc::new(
FuncKind::FieldAccessor(self.clone(), fld.clone()),
FuncKind::FieldAccessor(cls.clone(), fld.clone()),
Constness::Const,
return_kind,
fld_declname,
Expand All @@ -468,7 +472,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
let read_mut_func = if constness_filter.map_or(true, |c| c.is_mut()) {
Some(Func::new_desc(
FuncDesc::new(
FuncKind::FieldAccessor(self.clone(), fld.clone()),
FuncKind::FieldAccessor(cls.clone(), fld.clone()),
Constness::Mut,
return_kind,
format!("{fld_declname}Mut"),
Expand All @@ -489,7 +493,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
let single_read_func = if constness_filter.map_or(true, |c| c == fld_const) {
Some(Func::new_desc(
FuncDesc::new(
FuncKind::FieldAccessor(self.clone(), fld.clone()),
FuncKind::FieldAccessor(cls.clone(), fld.clone()),
fld_const,
return_kind,
fld_declname,
Expand Down Expand Up @@ -518,7 +522,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
let (first_letter, rest) = fld_declname.capitalize_first_ascii_letter().expect("Empty fld_declname");
Some(Func::new_desc(
FuncDesc::new(
FuncKind::FieldAccessor(self.clone(), fld.clone()),
FuncKind::FieldAccessor(cls.clone(), fld.clone()),
Constness::Mut,
ReturnKind::InfallibleNaked,
format!("set{first_letter}{rest}"),
Expand All @@ -545,9 +549,9 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
.or_else(|| write_yield.take())
})
};
fields.flat_map(accessor_generator).collect()
FieldMethodsIter::Clang(fields.iter().flat_map(accessor_generator))
}
Self::Desc(_) => vec![],
Self::Desc(_) => FieldMethodsIter::Desc,
}
}

Expand All @@ -574,15 +578,13 @@ impl<'tu, 'ge> Class<'tu, 'ge> {

pub fn generated_types(&self) -> Vec<GeneratedType<'tu, 'ge>> {
self
.fields()
.fields(|f| f.exclude_kind().is_included())
.into_iter()
.filter(|f| f.exclude_kind().is_included())
.flat_map(|f| f.type_ref().generated_types())
.chain(
self
.methods()
.methods(|m| m.exclude_kind().is_included())
.into_iter()
.filter(|m| m.exclude_kind().is_included())
.flat_map(|m| m.generated_types()),
)
.collect()
Expand Down Expand Up @@ -837,3 +839,19 @@ impl<'tu, 'ge> TemplateKind<'tu, 'ge> {
}
}
}

pub enum FieldMethodsIter<'tu: 'ge, 'ge, I: Iterator<Item = Func<'tu, 'ge>>> {
Clang(I),
Desc,
}

impl<'tu, 'ge, I: Iterator<Item = Func<'tu, 'ge>>> Iterator for FieldMethodsIter<'tu, 'ge, I> {
type Item = Func<'tu, 'ge>;

fn next(&mut self) -> Option<Self::Item> {
match self {
FieldMethodsIter::Clang(iter) => iter.next(),
FieldMethodsIter::Desc => None,
}
}
}
9 changes: 3 additions & 6 deletions binding-generator/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ pub fn render_constant_cpp(tokens: &[Token]) -> String {

pub fn render_evaluation_result_rust(result: EvaluationResult) -> Value {
match result {
EvaluationResult::Unexposed => {
panic!("Can't render evaluation result")
}
EvaluationResult::Unexposed => panic!("Can't render evaluation result"),
EvaluationResult::SignedInteger(x) => Value {
kind: ValueKind::Integer,
value: x.to_string(),
Expand Down Expand Up @@ -135,9 +133,7 @@ impl<'tu> Const<'tu> {
.to_string(),
}),
EntityKind::VarDecl => self.entity.evaluate().map(render_evaluation_result_rust),
_ => {
unreachable!("Invalid entity type for constant")
}
_ => unreachable!("Invalid entity type for constant"),
}
}
}
Expand Down Expand Up @@ -187,6 +183,7 @@ impl<'me> NameDebug<'me> for &'me Const<'_> {
pub enum ValueKind {
Integer,
UnsignedInteger,
Usize,
Float,
Double,
String,
Expand Down
1 change: 1 addition & 0 deletions binding-generator/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl DefaultElement {
}

pub fn is_public(entity: Entity) -> bool {
// MSRV: use `is_none_or` when MSRV is 1.82
entity.get_accessibility().map_or(true, |a| Accessibility::Public == a)
}

Expand Down
11 changes: 5 additions & 6 deletions binding-generator/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,10 @@ impl<'tu, 'ge> Func<'tu, 'ge> {

pub fn is_clone(&self) -> bool {
if self.cpp_name(CppNameStyle::Declaration) == "clone" {
if let Some(c) = self.kind().as_instance_method() {
!self.has_arguments() && self.return_type_ref().kind().as_class().is_some_and(|r| r.as_ref() == c)
} else {
false
}
self
.kind()
.as_instance_method()
.is_some_and(|c| !self.has_arguments() && self.return_type_ref().kind().as_class().is_some_and(|r| r.as_ref() == c))
} else {
false
}
Expand All @@ -449,7 +448,7 @@ impl<'tu, 'ge> Func<'tu, 'ge> {
&Self::Clang { entity, gen_env, .. } => {
let mut out = match self.kind().as_ref() {
FuncKind::Constructor(cls) => cls.type_ref(),
// `operator =` returns a reference to the `self` value and it's quite cumbersome to handle correctly
// `operator =` returns a reference to the `self` value, and it's quite cumbersome to handle correctly
FuncKind::InstanceOperator(_, OperatorKind::Set) => TypeRefDesc::void(),
FuncKind::Function
| FuncKind::InstanceMethod(..)
Expand Down
12 changes: 4 additions & 8 deletions binding-generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,16 +361,13 @@ pub struct Generator {

impl Drop for Generator {
fn drop(&mut self) {
#[cfg(any(not(windows), feature = "clang-runtime"))]
{
if !(cfg!(windows) && cfg!(feature = "clang-runtime") && clang::get_version().contains(" 19.")) {
// `clang` has an issue on Windows when running with `runtime` feature and clang-19:
// https://github.com/KyleMayes/clang-rs/issues/63
// So we avoid dropping clang in that case as a workaround.
// `clang::get_version()` is string like "Apple clang version 15.0.0 (clang-1500.1.0.2.5)"
if !clang::get_version().contains(" 19.") {
unsafe {
ManuallyDrop::drop(&mut self.clang);
}
unsafe {
ManuallyDrop::drop(&mut self.clang);
}
}
}
Expand Down Expand Up @@ -448,8 +445,7 @@ impl Generator {
.collect::<Vec<_>>();
args.push("-DOCVRS_PARSING_HEADERS".into());
args.push("-includeocvrs_common.hpp".into());
// need to have c++14 here because VS headers contain features that require it
args.push("-std=c++14".into());
args.push("-std=c++17".into());
// allow us to use some custom clang args
let clang_arg = env::var_os("OPENCV_CLANG_ARGS");
if let Some(clang_arg) = clang_arg.as_ref().and_then(|s| s.to_str()) {
Expand Down
4 changes: 2 additions & 2 deletions binding-generator/src/iterator_ext.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::StringExt;

pub trait IteratorExt {
fn join(&mut self, sep: &str) -> String;
fn join(self, sep: &str) -> String;
}

impl<T: Iterator<Item = impl AsRef<str>>> IteratorExt for T {
fn join(&mut self, sep: &str) -> String {
fn join(self, sep: &str) -> String {
let mut out = String::new();
out.extend_join(self, sep);
out
Expand Down
1 change: 0 additions & 1 deletion binding-generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub use generator_env::{ClassKindOverride, ExportConfig, GeneratorEnv};
pub use iterator_ext::IteratorExt;
pub use map_borrowed::CowMapBorrowedExt;
use memoize::{MemoizeMap, MemoizeMapExt};
use name_pool::NamePool;
use smart_ptr::SmartPtr;
pub use string_ext::{CompiledInterpolation, StrExt, StringExt};
use tuple::Tuple;
Expand Down
5 changes: 0 additions & 5 deletions binding-generator/src/name_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ impl NamePool {
out
}

pub fn add_name(&mut self, name: impl Into<Cow<'static, str>>) -> MakeUniqueNameResult {
let mut name = name.into();
self.make_unique_name(&mut name)
}

pub fn into_disambiguator<T, I, CB>(mut self, args: I, mut name_cb: CB) -> impl Iterator<Item = (String, T)>
where
I: IntoIterator<Item = T>,
Expand Down
5 changes: 2 additions & 3 deletions binding-generator/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub use argument_override::{
arg_override_factory, property_override_factory, return_override_factory, ArgOverride, PropertyOverride, ReturnOverride,
ARG_OVERRIDE_SELF,
};
pub use const_tweak::CONST_TYPE_OVERRIDE;
pub use element_exclude_kind::ELEMENT_EXCLUDE_KIND;
pub use element_export_tweak::ELEMENT_EXPORT_TWEAK;
pub use force_infallible::{force_infallible_factory, ForceInfallible};
Expand All @@ -70,6 +71,7 @@ use crate::type_ref::TypeRef;

mod argument_names;
mod argument_override;
mod const_tweak;
mod element_exclude_kind;
mod element_export_tweak;
mod force_infallible;
Expand Down Expand Up @@ -168,9 +170,6 @@ impl Settings {
}
}

// fixme, generalize, make it use constant::ValueKind
pub static CONST_TYPE_USIZE: Lazy<HashSet<&str>> = Lazy::new(|| HashSet::from(["Mat_AUTO_STEP"]));

/// map of reserved Rust keywords and their replacement to be used in var, function and class names
/// key: reserved keyword
/// value: replacement
Expand Down
8 changes: 8 additions & 0 deletions binding-generator/src/settings/const_tweak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use std::collections::HashMap;

use once_cell::sync::Lazy;

use crate::constant::ValueKind;

pub static CONST_TYPE_OVERRIDE: Lazy<HashMap<&str, ValueKind>> =
Lazy::new(|| HashMap::from([("Mat_AUTO_STEP", ValueKind::Usize)]));
Loading

0 comments on commit c43f377

Please sign in to comment.