Skip to content

Commit

Permalink
ir: Support hiding enum variants.
Browse files Browse the repository at this point in the history
Signed-off-by: Emilio Cobos Álvarez <[email protected]>
  • Loading branch information
emilio committed Jan 10, 2017
1 parent 8183e61 commit cbbd9be
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
9 changes: 5 additions & 4 deletions libbindgen/src/chooser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! A public API for more fine-grained customization of bindgen behavior.
pub use ir::int::IntKind;
pub use ir::enum_ty::EnumVariantValue;
pub use ir::enum_ty::{EnumVariantValue, EnumVariantCustomBehavior};
use std::fmt;

/// A trait to allow configuring different kinds of types in different
Expand All @@ -16,10 +16,11 @@ pub trait TypeChooser: fmt::Debug {
/// This function should return whether, given the a given enum variant
/// name, and value, returns whether this enum variant will forcibly be a
/// constant.
fn constify_enum_variant(&self,
fn enum_variant_behavior(&self,
_enum_name: Option<&str>,
_variant_name: &str,
_variant_value: EnumVariantValue) -> bool {
false
_variant_value: EnumVariantValue)
-> Option<EnumVariantCustomBehavior> {
None
}
}
4 changes: 4 additions & 0 deletions libbindgen/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1677,6 +1677,10 @@ impl CodeGenerator for Enum {
let variant = iter.next()
.unwrap_or_else(|| constified_variants.remove(0));

if variant.hidden() {
continue;
}

if variant.force_constification() && iter.peek().is_some() {
constified_variants.push(variant);
continue;
Expand Down
52 changes: 38 additions & 14 deletions libbindgen/src/ir/enum_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ use super::context::{BindgenContext, ItemId};
use super::item::Item;
use super::ty::TypeKind;

/// An enum representing custom handling that can be given to a variant.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EnumVariantCustomBehavior {
/// This variant will be constified, that is, forced to generate a constant.
Constify,
/// This variant will be hidden entirely from the resulting enum.
Hide,
}

/// A C/C++ enumeration.
#[derive(Debug)]
pub struct Enum {
Expand Down Expand Up @@ -80,16 +89,25 @@ impl Enum {
};
if let Some(val) = value {
let name = cursor.spelling();
let should_constify = ctx.type_chooser()
.map_or(false, |c| {
c.constify_enum_variant(type_name, &name, val)
}) ||
Annotations::new(&cursor).map_or(false, |anno| {
anno.constify_enum_variant()
let custom_behavior = ctx.type_chooser()
.and_then(|t| {
t.enum_variant_behavior(type_name, &name, val)
})
.or_else(|| {
Annotations::new(&cursor).and_then(|anno| {
if anno.hide() {
Some(EnumVariantCustomBehavior::Hide)
} else if anno.constify_enum_variant() {
Some(EnumVariantCustomBehavior::Constify)
} else {
None
}
})
});

let comment = cursor.raw_comment();
variants.push(
EnumVariant::new(name, comment, val, should_constify));
EnumVariant::new(name, comment, val, custom_behavior));
}
}
CXChildVisit_Continue
Expand All @@ -110,10 +128,8 @@ pub struct EnumVariant {
/// The integer value of the variant.
val: EnumVariantValue,

/// Whether this value should explicitly be constified.
///
/// This allows us to solve situations as described in #392.
force_constify: bool,
/// The custom behavior this variant may have, if any.
custom_behavior: Option<EnumVariantCustomBehavior>,
}

/// A constant value assigned to an enumeration variant.
Expand All @@ -131,13 +147,13 @@ impl EnumVariant {
pub fn new(name: String,
comment: Option<String>,
val: EnumVariantValue,
force_constify: bool)
custom_behavior: Option<EnumVariantCustomBehavior>)
-> Self {
EnumVariant {
name: name,
comment: comment,
val: val,
force_constify: force_constify,
custom_behavior: custom_behavior,
}
}

Expand All @@ -154,6 +170,14 @@ impl EnumVariant {
/// Returns whether this variant should be enforced to be a constant by code
/// generation.
pub fn force_constification(&self) -> bool {
self.force_constify
self.custom_behavior
.map_or(false, |b| b == EnumVariantCustomBehavior::Constify)
}

/// Returns whether the current variant should be hidden completely from the
/// resulting rust enum.
pub fn hidden(&self) -> bool {
self.custom_behavior
.map_or(false, |b| b == EnumVariantCustomBehavior::Hide)
}
}
2 changes: 0 additions & 2 deletions libbindgen/tests/expectations/tests/constify-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue:
nsCSSPropertyID::eCSSProperty_COUNT_unexistingVariantValue;
pub const nsCSSPropertyID_eCSSProperty_COUNT: nsCSSPropertyID =
nsCSSPropertyID::eCSSPropertyAlias_aa;
pub const nsCSSPropertyID_eCSSProperty_COUNT_DUMMY2: nsCSSPropertyID =
nsCSSPropertyID::eCSSProperty_b;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum nsCSSPropertyID {
Expand Down
2 changes: 1 addition & 1 deletion libbindgen/tests/headers/constify-enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ enum nsCSSPropertyID {
eCSSProperty_b,

eCSSProperty_COUNT, /**< <div rustbindgen constant></div> */
eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1, /**< <div rustbindgen constant></div> */
eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1, /**< <div rustbindgen hide></div> */

eCSSPropertyAlias_aa,
eCSSPropertyAlias_bb,
Expand Down

0 comments on commit cbbd9be

Please sign in to comment.