Rework Generator and GeneratorEnv
MODIFY
binding-generator/src/bin/binding-generator.rs
binding-generator/src/bin/binding-generator.rs
@@ -20,12 +20,8 @@ fn main() {
let version = args.next().expect("5th argument must be OpenCV version");
let version = version.to_str().expect("Not a valid version");
let debug = args.next().map_or(false, |x| x == "1");
- let mut module_file = src_cpp_dir.join(format!("{}.hpp", module));
- if !module_file.exists() {
- module_file = opencv_header_dir.join(format!("opencv2/{}.hpp", module));
- }
let clang = Clang::new().expect("Cannot initialize clang");
let bindings_writer = RustBindingWriter::new(&src_cpp_dir, &out_dir, module, version, debug);
- Generator::new(None, &opencv_header_dir, &src_cpp_dir, module, &clang)
- .process_file(&module_file, bindings_writer);
+ Generator::new(None, &opencv_header_dir, &src_cpp_dir, &clang)
+ .process_opencv_module(&module, bindings_writer);
}

MODIFY
binding-generator/src/generator.rs
binding-generator/src/generator.rs
@@ -47,12 +47,11 @@ pub trait GeneratorVisitor {
}
#[derive(Debug)]
-pub struct Generator<'m, 'c> {
+pub struct Generator<'g> {
clang_include_dirs: Vec<PathBuf>,
opencv_include_dir: PathBuf,
src_cpp_dir: PathBuf,
- module: &'m str,
- clang: &'c Clang,
+ clang: &'g Clang,
}
struct OpenCVWalker<'tu, V: GeneratorVisitor> {
@@ -312,8 +311,8 @@ impl<V: GeneratorVisitor> Drop for OpenCVWalker<'_, V> {
}
}
-impl<'m, 'c> Generator<'m, 'c> {
- pub fn new(clang_stdlib_include_dir: Option<&Path>, opencv_include_dir: &Path, src_cpp_dir: &Path, module: &'m str, clang: &'c Clang) -> Self {
+impl<'g> Generator<'g> {
+ pub fn new(clang_stdlib_include_dir: Option<&Path>, opencv_include_dir: &Path, src_cpp_dir: &Path, clang: &'g Clang) -> Self {
let clang_bin = clang_sys::support::Clang::find(None, &[]).expect("Can't find clang binary");
let mut clang_include_dirs = clang_bin.cpp_search_paths.unwrap_or_default();
if let Some(clang_stdlib_include_dir) = clang_stdlib_include_dir {
@@ -323,7 +322,6 @@ impl<'m, 'c> Generator<'m, 'c> {
clang_include_dirs,
opencv_include_dir: canonicalize(opencv_include_dir).expect("Can't canonicalize opencv_include_dir"),
src_cpp_dir: canonicalize(src_cpp_dir).expect("Can't canonicalize src_cpp_dir"),
- module,
clang,
}
}
@@ -340,21 +338,31 @@ impl<'m, 'c> Generator<'m, 'c> {
args
}
- pub fn process_file<V: GeneratorVisitor>(&self, file: &Path, visitor: V) {
+ pub fn process_module(&self, module: &str, entity_processor: impl FnOnce(Entity)) {
let index = Index::new(&self.clang, true, false);
- let top = index.parser(canonicalize(file).expect("Can't canonicalize file"))
+ let mut module_file = self.src_cpp_dir.join(format!("{}.hpp", module));
+ if !module_file.exists() {
+ module_file = self.opencv_include_dir.join(format!("opencv2/{}.hpp", module));
+ }
+ let root_tu = index.parser(module_file)
.arguments(&self.build_clang_command_line_args())
.detailed_preprocessing_record(true)
.skip_function_bodies(true)
.parse().expect("Cannot parse");
- let top_entity = top.get_entity();
+ entity_processor(root_tu.get_entity());
+ }
+
+ pub fn process_opencv_module(&self, module: &str, visitor: impl GeneratorVisitor) {
+ self.process_module(module, |root_entity| {
+ let gen_env = GeneratorEnv::new(root_entity, module);
let opencv_walker = OpenCVWalker::new(
&self.opencv_include_dir,
visitor,
- GeneratorEnv::new(top_entity, self.module),
+ gen_env,
);
- let walker = EntityWalker::new(top_entity);
+ let walker = EntityWalker::new(root_entity);
walker.walk_opencv_entities(opencv_walker);
+ });
}
}

MODIFY
binding-generator/src/generator_env.rs
binding-generator/src/generator_env.rs
@@ -42,11 +42,21 @@ impl ExportConfig {
type ExportIdx = (PathBuf, u32, u32);
-struct CacheFiller<'ge, 'tu> {
+struct DBPopulator<'ge, 'tu> {
gen_env: &'ge mut GeneratorEnv<'tu>,
}
-impl<'tu> EntityWalkerVisitor<'tu> for CacheFiller<'_, 'tu> {
+impl DBPopulator<'_, '_> {
+ fn add_func_comment(&mut self, entity: Entity) {
+ let raw_comment = entity.get_comment().unwrap_or_default();
+ if !raw_comment.is_empty() && !raw_comment.contains("@overload") {
+ let name = entity.cpp_fullname().into_owned();
+ self.gen_env.func_comments.insert(name, comment::strip_comment_markers(&raw_comment));
+ }
+ }
+}
+
+impl<'tu> EntityWalkerVisitor<'tu> for DBPopulator<'_, 'tu> {
fn wants_file(&mut self, path: &Path) -> bool {
is_opencv_path(path)
|| path.ends_with("ocvrs_resolve_types.hpp")
@@ -71,7 +81,7 @@ impl<'tu> EntityWalkerVisitor<'tu> for CacheFiller<'_, 'tu> {
// }
EntityKind::Constructor | EntityKind::Method | EntityKind::FunctionTemplate
| EntityKind::ConversionFunction => {
- self.gen_env.add_func_comment(c);
+ self.add_func_comment(c);
}
_ => {}
}
@@ -79,7 +89,7 @@ impl<'tu> EntityWalkerVisitor<'tu> for CacheFiller<'_, 'tu> {
});
}
EntityKind::FunctionDecl => {
- self.gen_env.add_func_comment(entity);
+ self.add_func_comment(entity);
}
_ => {}
}
@@ -88,7 +98,6 @@ impl<'tu> EntityWalkerVisitor<'tu> for CacheFiller<'_, 'tu> {
}
pub struct GeneratorEnv<'tu> {
- root_entity: Entity<'tu>,
module: &'tu str,
export_map: HashMap<ExportIdx, ExportConfig>,
pub func_names: NamePool,
@@ -101,7 +110,6 @@ pub struct GeneratorEnv<'tu> {
impl<'tu> GeneratorEnv<'tu> {
pub fn new(root_entity: Entity<'tu>, module: &'tu str) -> Self {
let mut out = Self {
- root_entity,
module,
export_map: HashMap::with_capacity(1024),
func_names: NamePool::with_capacity(512),
@@ -110,23 +118,11 @@ impl<'tu> GeneratorEnv<'tu> {
class_kind_cache: MemoizeMap::new(HashMap::with_capacity(32)),
type_resolve_cache: HashMap::with_capacity(32),
};
- out.fill_caches();
+ let walker = EntityWalker::new(root_entity);
+ walker.walk_opencv_entities(DBPopulator { gen_env: &mut out });
out
}
- fn fill_caches(&mut self) {
- let walker = EntityWalker::new(self.root_entity);
- walker.walk_opencv_entities(CacheFiller { gen_env: self });
- }
-
- fn add_func_comment(&mut self, entity: Entity<'tu>) {
- let raw_comment = entity.get_comment().unwrap_or_default();
- if !raw_comment.is_empty() && !raw_comment.contains("@overload") {
- let name = entity.cpp_fullname().into_owned();
- self.func_comments.insert(name, comment::strip_comment_markers(&raw_comment));
- }
- }
-
pub fn module(&self) -> &str {
self.module
}

MODIFY
build.rs
build.rs
@@ -102,10 +102,6 @@ mod generator {
let start = Instant::now();
let shown_args = AtomicBool::new(false);
let build_func = |module: &String| {
- let mut module_file = SRC_CPP_DIR.join(format!("{}.hpp", module));
- if !module_file.exists() {
- module_file = opencv_dir.join(format!("{}.hpp", module));
- }
let bindings_writer = binding_generator::writer::RustBindingWriter::new(
&*SRC_CPP_DIR,
&*OUT_DIR,
@@ -115,11 +111,11 @@ mod generator {
);
let clang_stdlib_include_dir = env::var_os("OPENCV_CLANG_STDLIB_PATH")
.map(|p| PathBuf::from(p));
- let gen = binding_generator::Generator::new(clang_stdlib_include_dir.as_deref(), &opencv_header_dir, &*SRC_CPP_DIR, module, &clang);
+ let gen = binding_generator::Generator::new(clang_stdlib_include_dir.as_deref(), &opencv_header_dir, &*SRC_CPP_DIR, &clang);
if !shown_args.compare_and_swap(false, true, Ordering::Relaxed) {
eprintln!("=== Clang command line args: {:#?}", gen.build_clang_command_line_args());
}
- gen.process_file(&module_file, bindings_writer);
+ gen.process_opencv_module(&module, bindings_writer);
println!("Generated: {}", module);
};

Rework Generator and GeneratorEnv