From 9f632843b8b9dacbdc7a153868a4a9546e196e2e Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Fri, 17 May 2024 11:38:39 -0700 Subject: [PATCH] Generalize Item to expose documentation and generic params Closes #963 --- src/bindgen/ir/constant.rs | 10 +++++++++- src/bindgen/ir/enumeration.rs | 10 +++++++++- src/bindgen/ir/generic_path.rs | 6 ++++++ src/bindgen/ir/global.rs | 12 +++++++++++- src/bindgen/ir/item.rs | 11 +++++++++-- src/bindgen/ir/opaque.rs | 14 +++++++++----- src/bindgen/ir/structure.rs | 12 ++++++++---- src/bindgen/ir/typedef.rs | 18 ++++++++++-------- src/bindgen/ir/union.rs | 12 ++++++++---- src/bindgen/library.rs | 10 +++++----- src/bindgen/monomorph.rs | 12 ++++++------ 11 files changed, 90 insertions(+), 37 deletions(-) diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index 33fa86bc5..7f1f45a89 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -574,6 +574,10 @@ impl Item for Constant { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Constant(self.clone()) } @@ -589,6 +593,10 @@ impl Item for Constant { fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) { self.ty.resolve_declaration_types(resolver); } + + fn generic_params(&self) -> &GenericParams { + GenericParams::empty() + } } impl Constant { @@ -671,7 +679,7 @@ impl Constant { value = fields.iter().next().unwrap().1 } - language_backend.write_documentation(out, &self.documentation); + language_backend.write_documentation(out, self.documentation()); let allow_constexpr = config.constant.allow_constexpr && self.value.can_be_constexpr(); match config.language { diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index d98cae4ff..2e633a7df 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -318,7 +318,7 @@ impl Enum { } pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) { - if self.generic_params.len() > 0 { + if self.is_generic() { return; } @@ -467,6 +467,10 @@ impl Item for Enum { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Enum(self.clone()) } @@ -492,6 +496,10 @@ impl Item for Enum { } } + fn generic_params(&self) -> &GenericParams { + &self.generic_params + } + fn rename_for_config(&mut self, config: &Config) { config.export.rename(&mut self.export_name); diff --git a/src/bindgen/ir/generic_path.rs b/src/bindgen/ir/generic_path.rs index e97488d45..4610641ce 100644 --- a/src/bindgen/ir/generic_path.rs +++ b/src/bindgen/ir/generic_path.rs @@ -85,7 +85,13 @@ impl GenericParam { #[derive(Default, Debug, Clone)] pub struct GenericParams(pub Vec); +static EMPTY_GENERIC_PARAMS: GenericParams = GenericParams(Vec::new()); impl GenericParams { + /// An empty generic params, for convenience. + pub fn empty() -> &'static Self { + &EMPTY_GENERIC_PARAMS + } + pub fn load(generics: &syn::Generics) -> Result { let mut params = vec![]; for param in &generics.params { diff --git a/src/bindgen/ir/global.rs b/src/bindgen/ir/global.rs index 0d42bbc4f..cd8a1dac2 100644 --- a/src/bindgen/ir/global.rs +++ b/src/bindgen/ir/global.rs @@ -5,7 +5,9 @@ use crate::bindgen::config::Config; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; -use crate::bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Path, Type}; +use crate::bindgen::ir::{ + AnnotationSet, Cfg, Documentation, GenericParams, Item, ItemContainer, Path, Type, +}; use crate::bindgen::library::Library; #[derive(Debug, Clone)] @@ -87,6 +89,10 @@ impl Item for Static { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Static(self.clone()) } @@ -99,6 +105,10 @@ impl Item for Static { self.ty.resolve_declaration_types(resolver); } + fn generic_params(&self) -> &GenericParams { + GenericParams::empty() + } + fn add_dependencies(&self, library: &Library, out: &mut Dependencies) { self.ty.add_dependencies(library, out); } diff --git a/src/bindgen/ir/item.rs b/src/bindgen/ir/item.rs index 0c8b7c344..03e1c153a 100644 --- a/src/bindgen/ir/item.rs +++ b/src/bindgen/ir/item.rs @@ -9,8 +9,8 @@ use crate::bindgen::config::Config; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; use crate::bindgen::ir::{ - AnnotationSet, Cfg, Constant, Enum, GenericArgument, OpaqueItem, Path, Static, Struct, Typedef, - Union, + AnnotationSet, Cfg, Constant, Documentation, Enum, GenericArgument, GenericParams, OpaqueItem, + Path, Static, Struct, Typedef, Union, }; use crate::bindgen::library::Library; use crate::bindgen::monomorph::Monomorphs; @@ -27,6 +27,7 @@ pub trait Item { fn cfg(&self) -> Option<&Cfg>; fn annotations(&self) -> &AnnotationSet; fn annotations_mut(&mut self) -> &mut AnnotationSet; + fn documentation(&self) -> &Documentation; fn container(&self) -> ItemContainer; @@ -36,6 +37,12 @@ pub trait Item { fn resolve_declaration_types(&mut self, _resolver: &DeclarationTypeResolver) { unimplemented!() } + fn generic_params(&self) -> &GenericParams; + + fn is_generic(&self) -> bool { + !self.generic_params().is_empty() + } + fn rename_for_config(&mut self, _config: &Config) {} fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) {} fn instantiate_monomorph( diff --git a/src/bindgen/ir/opaque.rs b/src/bindgen/ir/opaque.rs index b14a1c3ba..4527e3ca8 100644 --- a/src/bindgen/ir/opaque.rs +++ b/src/bindgen/ir/opaque.rs @@ -78,6 +78,10 @@ impl Item for OpaqueItem { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::OpaqueItem(self.clone()) } @@ -86,6 +90,10 @@ impl Item for OpaqueItem { resolver.add_struct(&self.path); } + fn generic_params(&self) -> &GenericParams { + &self.generic_params + } + fn rename_for_config(&mut self, config: &Config) { config.export.rename(&mut self.export_name); } @@ -98,11 +106,7 @@ impl Item for OpaqueItem { library: &Library, out: &mut Monomorphs, ) { - assert!( - !self.generic_params.is_empty(), - "{} is not generic", - self.path - ); + assert!(self.is_generic(), "{} is not generic", self.path); // We can be instantiated with less generic params because of default // template parameters, or because of empty types that we remove during diff --git a/src/bindgen/ir/structure.rs b/src/bindgen/ir/structure.rs index 1f1995b73..49ae5da85 100644 --- a/src/bindgen/ir/structure.rs +++ b/src/bindgen/ir/structure.rs @@ -150,10 +150,6 @@ impl Struct { } } - pub fn is_generic(&self) -> bool { - self.generic_params.len() > 0 - } - pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) { // Generic structs can instantiate monomorphs only once they've been // instantiated. See `instantiate_monomorph` for more details. @@ -266,6 +262,10 @@ impl Item for Struct { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Struct(self.clone()) } @@ -284,6 +284,10 @@ impl Item for Struct { } } + fn generic_params(&self) -> &GenericParams { + &self.generic_params + } + fn rename_for_config(&mut self, config: &Config) { // Rename the name of the struct if !(self.has_tag_field && config.language == Language::Cxx) { diff --git a/src/bindgen/ir/typedef.rs b/src/bindgen/ir/typedef.rs index dbfdc5ba8..58095878d 100644 --- a/src/bindgen/ir/typedef.rs +++ b/src/bindgen/ir/typedef.rs @@ -89,18 +89,12 @@ impl Typedef { } } - pub fn is_generic(&self) -> bool { - self.generic_params.len() > 0 - } - pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) { // Generic structs can instantiate monomorphs only once they've been // instantiated. See `instantiate_monomorph` for more details. - if self.is_generic() { - return; + if !self.is_generic() { + self.aliased.add_monomorphs(library, out); } - - self.aliased.add_monomorphs(library, out); } pub fn mangle_paths(&mut self, monomorphs: &Monomorphs) { @@ -129,6 +123,10 @@ impl Item for Typedef { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Typedef(self.clone()) } @@ -141,6 +139,10 @@ impl Item for Typedef { self.aliased.resolve_declaration_types(resolver); } + fn generic_params(&self) -> &GenericParams { + &self.generic_params + } + fn rename_for_config(&mut self, config: &Config) { config.export.rename(&mut self.export_name); self.aliased.rename_for_config(config, &self.generic_params); diff --git a/src/bindgen/ir/union.rs b/src/bindgen/ir/union.rs index 32db72648..410e21a27 100644 --- a/src/bindgen/ir/union.rs +++ b/src/bindgen/ir/union.rs @@ -100,10 +100,6 @@ impl Union { } } - pub fn is_generic(&self) -> bool { - self.generic_params.len() > 0 - } - pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) { // Generic unions can instantiate monomorphs only once they've been // instantiated. See `instantiate_monomorph` for more details. @@ -144,6 +140,10 @@ impl Item for Union { &mut self.annotations } + fn documentation(&self) -> &Documentation { + &self.documentation + } + fn container(&self) -> ItemContainer { ItemContainer::Union(self.clone()) } @@ -158,6 +158,10 @@ impl Item for Union { } } + fn generic_params(&self) -> &GenericParams { + &self.generic_params + } + fn rename_for_config(&mut self, config: &Config) { config.export.rename(&mut self.export_name); for field in &mut self.fields { diff --git a/src/bindgen/library.rs b/src/bindgen/library.rs index 2fd79fed4..9d61257f9 100644 --- a/src/bindgen/library.rs +++ b/src/bindgen/library.rs @@ -428,11 +428,11 @@ impl Library { } // Remove structs and opaque items that are generic - self.opaque_items.filter(|x| x.generic_params.len() > 0); - self.structs.filter(|x| x.generic_params.len() > 0); - self.unions.filter(|x| x.generic_params.len() > 0); - self.enums.filter(|x| x.generic_params.len() > 0); - self.typedefs.filter(|x| x.generic_params.len() > 0); + self.opaque_items.filter(|x| x.is_generic()); + self.structs.filter(|x| x.is_generic()); + self.unions.filter(|x| x.is_generic()); + self.enums.filter(|x| x.is_generic()); + self.typedefs.filter(|x| x.is_generic()); // Mangle the paths that remain self.unions diff --git a/src/bindgen/monomorph.rs b/src/bindgen/monomorph.rs index db6dce63e..2dab9cf46 100644 --- a/src/bindgen/monomorph.rs +++ b/src/bindgen/monomorph.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use std::mem; use crate::bindgen::ir::{ - Enum, GenericArgument, GenericPath, OpaqueItem, Path, Struct, Typedef, Union, + Enum, GenericArgument, GenericPath, Item, OpaqueItem, Path, Struct, Typedef, Union, }; use crate::bindgen::library::Library; @@ -34,7 +34,7 @@ impl Monomorphs { ) { let replacement_path = GenericPath::new(generic.path.clone(), arguments); - debug_assert!(generic.generic_params.len() > 0); + debug_assert!(generic.is_generic()); debug_assert!(!self.contains(&replacement_path)); self.replacements @@ -54,7 +54,7 @@ impl Monomorphs { ) { let replacement_path = GenericPath::new(generic.path.clone(), arguments); - debug_assert!(generic.generic_params.len() > 0); + debug_assert!(generic.is_generic()); debug_assert!(!self.contains(&replacement_path)); self.replacements @@ -74,7 +74,7 @@ impl Monomorphs { ) { let replacement_path = GenericPath::new(generic.path.clone(), arguments); - debug_assert!(generic.generic_params.len() > 0); + debug_assert!(generic.is_generic()); debug_assert!(!self.contains(&replacement_path)); self.replacements @@ -93,7 +93,7 @@ impl Monomorphs { ) { let replacement_path = GenericPath::new(generic.path.clone(), arguments); - debug_assert!(generic.generic_params.len() > 0); + debug_assert!(generic.is_generic()); debug_assert!(!self.contains(&replacement_path)); self.replacements @@ -110,7 +110,7 @@ impl Monomorphs { ) { let replacement_path = GenericPath::new(generic.path.clone(), arguments); - debug_assert!(generic.generic_params.len() > 0); + debug_assert!(generic.is_generic()); debug_assert!(!self.contains(&replacement_path)); self.replacements