Skip to content

Commit

Permalink
Use field_visibility callback for new-type aliases
Browse files Browse the repository at this point in the history
The `field_visibility` callback is now called in case of alias new-type and new-type-deref with the type name and field_name set to `"0"`
  • Loading branch information
nyurik committed Nov 2, 2024
1 parent 8a6d851 commit 901a4a0
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
10 changes: 10 additions & 0 deletions bindgen-tests/tests/expectations/tests/issue-2966.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions bindgen-tests/tests/headers/issue-2966.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// bindgen-flags: --default-alias-style=new_type
// bindgen-parse-callbacks: type-visibility

typedef const char * pub_var1;
typedef const char * pubcrate_var2;
typedef const char * private_var3;
27 changes: 25 additions & 2 deletions bindgen-tests/tests/parse_callbacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ struct FieldVisibility {
}

/// Implements the `field_visibility` function of the trait by checking if the
/// field name starts with `private_`. If it does it makes it private, if it
/// doesn't it makes it public, taking into account the default visibility.
/// field name starts with `private_`. If it does, it makes it private, if it
/// doesn't, it makes it public, taking into account the default visibility.
impl ParseCallbacks for FieldVisibility {
fn field_visibility(
&self,
Expand All @@ -113,6 +113,28 @@ impl ParseCallbacks for FieldVisibility {
}
}

#[derive(Debug)]
struct TypeVisibility;

/// Implements the `field_visibility` function of the trait by checking the
/// type name. Depending on name prefix, it will return a different visibility.
impl ParseCallbacks for TypeVisibility {
fn field_visibility(
&self,
FieldInfo { type_name, .. }: FieldInfo,
) -> Option<FieldVisibilityKind> {
if type_name.starts_with("private_") {
Some(FieldVisibilityKind::Private)
} else if type_name.starts_with("pubcrate_") {
Some(FieldVisibilityKind::PublicCrate)
} else if type_name.starts_with("pub_") {
Some(FieldVisibilityKind::Public)
} else {
None
}
}
}

#[derive(Debug)]
pub(super) struct WrapAsVariadicFn;

Expand All @@ -129,6 +151,7 @@ pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
Box::new(BlocklistedTypeImplementsTrait)
}
"wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn),
"type-visibility" => Box::new(TypeVisibility),
call_back => {
if let Some(prefix) =
call_back.strip_prefix("remove-function-prefix-")
Expand Down
12 changes: 10 additions & 2 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,13 +1099,21 @@ impl CodeGenerator for Type {
});
}

let access_spec =
access_specifier(ctx.options().default_visibility);
tokens.append_all(match alias_style {
AliasVariation::TypeAlias => quote! {
= #inner_rust_type ;
},
AliasVariation::NewType | AliasVariation::NewTypeDeref => {
let visibility = ctx
.options()
.last_callback(|cb| {
cb.field_visibility(FieldInfo {
type_name: &item.canonical_name(ctx),
field_name: "0",
})
})
.unwrap_or(ctx.options().default_visibility);
let access_spec = access_specifier(visibility);
quote! {
(#access_spec #inner_rust_type) ;
}
Expand Down

0 comments on commit 901a4a0

Please sign in to comment.