From cbbd9be7206929564318b7f5b853713ae93a9eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 10 Jan 2017 14:02:49 +0100 Subject: [PATCH] ir: Support hiding enum variants. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- libbindgen/src/chooser.rs | 9 ++-- libbindgen/src/codegen/mod.rs | 4 ++ libbindgen/src/ir/enum_ty.rs | 52 ++++++++++++++----- .../tests/expectations/tests/constify-enum.rs | 2 - libbindgen/tests/headers/constify-enum.h | 2 +- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/libbindgen/src/chooser.rs b/libbindgen/src/chooser.rs index 660f423c1b..51392d70e1 100644 --- a/libbindgen/src/chooser.rs +++ b/libbindgen/src/chooser.rs @@ -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 @@ -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 { + None } } diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 479e0d8f4c..249afb80db 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -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; diff --git a/libbindgen/src/ir/enum_ty.rs b/libbindgen/src/ir/enum_ty.rs index 7d6d1a6ec3..ca4e77db5e 100644 --- a/libbindgen/src/ir/enum_ty.rs +++ b/libbindgen/src/ir/enum_ty.rs @@ -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 { @@ -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 @@ -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, } /// A constant value assigned to an enumeration variant. @@ -131,13 +147,13 @@ impl EnumVariant { pub fn new(name: String, comment: Option, val: EnumVariantValue, - force_constify: bool) + custom_behavior: Option) -> Self { EnumVariant { name: name, comment: comment, val: val, - force_constify: force_constify, + custom_behavior: custom_behavior, } } @@ -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) } } diff --git a/libbindgen/tests/expectations/tests/constify-enum.rs b/libbindgen/tests/expectations/tests/constify-enum.rs index 356aaa05c6..989c5197ac 100644 --- a/libbindgen/tests/expectations/tests/constify-enum.rs +++ b/libbindgen/tests/expectations/tests/constify-enum.rs @@ -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 { diff --git a/libbindgen/tests/headers/constify-enum.h b/libbindgen/tests/headers/constify-enum.h index f2771e5930..a5b4052c78 100644 --- a/libbindgen/tests/headers/constify-enum.h +++ b/libbindgen/tests/headers/constify-enum.h @@ -4,7 +4,7 @@ enum nsCSSPropertyID { eCSSProperty_b, eCSSProperty_COUNT, /**<
*/ - eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1, /**<
*/ + eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1, /**<
*/ eCSSPropertyAlias_aa, eCSSPropertyAlias_bb,