From 2540b8211f0781b96242b6ccc88fe124866b0810 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Fri, 22 Sep 2017 12:04:17 +0300 Subject: Rename derive_debug → impl_debug. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/codegen/derive_debug.rs | 219 -------------------------------------------- src/codegen/impl_debug.rs | 219 ++++++++++++++++++++++++++++++++++++++++++++ src/codegen/mod.rs | 4 +- 3 files changed, 221 insertions(+), 221 deletions(-) delete mode 100644 src/codegen/derive_debug.rs create mode 100644 src/codegen/impl_debug.rs diff --git a/src/codegen/derive_debug.rs b/src/codegen/derive_debug.rs deleted file mode 100644 index 7ef108da..00000000 --- a/src/codegen/derive_debug.rs +++ /dev/null @@ -1,219 +0,0 @@ -use ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods}; -use ir::context::BindgenContext; -use ir::derive::CanTriviallyDeriveDebug; -use ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName}; -use ir::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, TypeKind}; -use quote; - -pub fn gen_debug_impl( - ctx: &BindgenContext, - fields: &[Field], - item: &Item, - kind: CompKind, -) -> quote::Tokens { - let struct_name = item.canonical_name(ctx); - let mut format_string = format!("{} {{{{ ", struct_name); - let mut tokens = vec![]; - - if item.is_opaque(ctx, &()) { - format_string.push_str("opaque"); - } else { - match kind { - CompKind::Union => { - format_string.push_str("union"); - } - CompKind::Struct => { - let processed_fields = fields.iter().filter_map(|f| match f { - &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), - &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), - }); - - - for (i, (fstring, toks)) in processed_fields.enumerate() { - if i > 0 { - format_string.push_str(", "); - } - tokens.extend(toks); - format_string.push_str(&fstring); - } - } - } - } - - format_string.push_str(" }}"); - tokens.insert(0, quote! { #format_string }); - - quote! { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, #( #tokens ),*) - } - } -} - -/// A trait for the things which we can codegen tokens that contribute towards a -/// generated `impl Debug`. -pub trait ImplDebug<'a> { - /// Any extra parameter required by this a particular `ImplDebug` implementation. - type Extra; - - /// Generate a format string snippet to be included in the larger `impl Debug` - /// format string, and the code to get the format string's interpolation values. - fn impl_debug( - &self, - ctx: &BindgenContext, - extra: Self::Extra, - ) -> Option<(String, Vec)>; -} - -impl<'a> ImplDebug<'a> for FieldData { - type Extra = (); - - fn impl_debug( - &self, - ctx: &BindgenContext, - _: Self::Extra, - ) -> Option<(String, Vec)> { - if let Some(name) = self.name() { - ctx.resolve_item(self.ty()).impl_debug(ctx, name) - } else { - None - } - } -} - -impl<'a> ImplDebug<'a> for BitfieldUnit { - type Extra = (); - - fn impl_debug( - &self, - ctx: &BindgenContext, - _: Self::Extra, - ) -> Option<(String, Vec)> { - let mut format_string = String::new(); - let mut tokens = vec![]; - for (i, bu) in self.bitfields().iter().enumerate() { - if i > 0 { - format_string.push_str(", "); - } - format_string.push_str(&format!("{} : {{:?}}", bu.name())); - let name_ident = ctx.rust_ident_raw(bu.name()); - tokens.push(quote! { - self.#name_ident () - }); - } - - Some((format_string, tokens)) - } -} - -impl<'a> ImplDebug<'a> for Item { - type Extra = &'a str; - - fn impl_debug( - &self, - ctx: &BindgenContext, - name: &str, - ) -> Option<(String, Vec)> { - let name_ident = ctx.rust_ident_raw(name); - - // We don't know if blacklisted items `impl Debug` or not, so we can't - // add them to the format string we're building up. - if !ctx.whitelisted_items().contains(&self.id()) { - return None; - } - - let ty = match self.as_type() { - Some(ty) => ty, - None => { - return None; - } - }; - - fn debug_print( - name: &str, - name_ident: quote::Tokens, - ) -> Option<(String, Vec)> { - Some(( - format!("{}: {{:?}}", name), - vec![quote! { - self.#name_ident - }], - )) - } - - match *ty.kind() { - // Handle the simple cases. - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Function(..) | - TypeKind::Enum(..) | - TypeKind::Reference(..) | - TypeKind::BlockPointer | - TypeKind::UnresolvedTypeRef(..) | - TypeKind::ObjCInterface(..) | - TypeKind::ObjCId | - TypeKind::Comp(..) | - TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }), - - TypeKind::TemplateInstantiation(ref inst) => { - if inst.is_opaque(ctx, self) { - Some((format!("{}: opaque", name), vec![])) - } else { - debug_print(name, quote! { #name_ident }) - } - } - - // The generic is not required to implement Debug, so we can not debug print that type - TypeKind::TypeParam => { - Some((format!("{}: Non-debuggable generic", name), vec![])) - } - - TypeKind::Array(_, len) => { - // Generics are not required to implement Debug - if self.has_type_param_in_array(ctx) { - Some( - (format!("{}: Array with length {}", name, len), vec![]), - ) - } else if len < RUST_DERIVE_IN_ARRAY_LIMIT { - // The simple case - debug_print(name, quote! { #name_ident }) - } else { - // Let's implement our own print function - Some(( - format!("{}: [{{}}]", name), - vec![quote! { - self.#name_ident - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::() - }], - )) - } - } - - TypeKind::ResolvedTypeRef(t) | - TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => { - // We follow the aliases - ctx.resolve_item(t).impl_debug(ctx, name) - } - - TypeKind::Pointer(inner) => { - let inner_type = ctx.resolve_type(inner).canonical_type(ctx); - match *inner_type.kind() { - TypeKind::Function(ref sig) - if !sig.can_trivially_derive_debug() => { - Some((format!("{}: FunctionPointer", name), vec![])) - } - _ => debug_print(name, quote! { #name_ident }), - } - } - - TypeKind::Opaque => None, - } - } -} diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs new file mode 100644 index 00000000..7ef108da --- /dev/null +++ b/src/codegen/impl_debug.rs @@ -0,0 +1,219 @@ +use ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods}; +use ir::context::BindgenContext; +use ir::derive::CanTriviallyDeriveDebug; +use ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName}; +use ir::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, TypeKind}; +use quote; + +pub fn gen_debug_impl( + ctx: &BindgenContext, + fields: &[Field], + item: &Item, + kind: CompKind, +) -> quote::Tokens { + let struct_name = item.canonical_name(ctx); + let mut format_string = format!("{} {{{{ ", struct_name); + let mut tokens = vec![]; + + if item.is_opaque(ctx, &()) { + format_string.push_str("opaque"); + } else { + match kind { + CompKind::Union => { + format_string.push_str("union"); + } + CompKind::Struct => { + let processed_fields = fields.iter().filter_map(|f| match f { + &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), + &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), + }); + + + for (i, (fstring, toks)) in processed_fields.enumerate() { + if i > 0 { + format_string.push_str(", "); + } + tokens.extend(toks); + format_string.push_str(&fstring); + } + } + } + } + + format_string.push_str(" }}"); + tokens.insert(0, quote! { #format_string }); + + quote! { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, #( #tokens ),*) + } + } +} + +/// A trait for the things which we can codegen tokens that contribute towards a +/// generated `impl Debug`. +pub trait ImplDebug<'a> { + /// Any extra parameter required by this a particular `ImplDebug` implementation. + type Extra; + + /// Generate a format string snippet to be included in the larger `impl Debug` + /// format string, and the code to get the format string's interpolation values. + fn impl_debug( + &self, + ctx: &BindgenContext, + extra: Self::Extra, + ) -> Option<(String, Vec)>; +} + +impl<'a> ImplDebug<'a> for FieldData { + type Extra = (); + + fn impl_debug( + &self, + ctx: &BindgenContext, + _: Self::Extra, + ) -> Option<(String, Vec)> { + if let Some(name) = self.name() { + ctx.resolve_item(self.ty()).impl_debug(ctx, name) + } else { + None + } + } +} + +impl<'a> ImplDebug<'a> for BitfieldUnit { + type Extra = (); + + fn impl_debug( + &self, + ctx: &BindgenContext, + _: Self::Extra, + ) -> Option<(String, Vec)> { + let mut format_string = String::new(); + let mut tokens = vec![]; + for (i, bu) in self.bitfields().iter().enumerate() { + if i > 0 { + format_string.push_str(", "); + } + format_string.push_str(&format!("{} : {{:?}}", bu.name())); + let name_ident = ctx.rust_ident_raw(bu.name()); + tokens.push(quote! { + self.#name_ident () + }); + } + + Some((format_string, tokens)) + } +} + +impl<'a> ImplDebug<'a> for Item { + type Extra = &'a str; + + fn impl_debug( + &self, + ctx: &BindgenContext, + name: &str, + ) -> Option<(String, Vec)> { + let name_ident = ctx.rust_ident_raw(name); + + // We don't know if blacklisted items `impl Debug` or not, so we can't + // add them to the format string we're building up. + if !ctx.whitelisted_items().contains(&self.id()) { + return None; + } + + let ty = match self.as_type() { + Some(ty) => ty, + None => { + return None; + } + }; + + fn debug_print( + name: &str, + name_ident: quote::Tokens, + ) -> Option<(String, Vec)> { + Some(( + format!("{}: {{:?}}", name), + vec![quote! { + self.#name_ident + }], + )) + } + + match *ty.kind() { + // Handle the simple cases. + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Function(..) | + TypeKind::Enum(..) | + TypeKind::Reference(..) | + TypeKind::BlockPointer | + TypeKind::UnresolvedTypeRef(..) | + TypeKind::ObjCInterface(..) | + TypeKind::ObjCId | + TypeKind::Comp(..) | + TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }), + + TypeKind::TemplateInstantiation(ref inst) => { + if inst.is_opaque(ctx, self) { + Some((format!("{}: opaque", name), vec![])) + } else { + debug_print(name, quote! { #name_ident }) + } + } + + // The generic is not required to implement Debug, so we can not debug print that type + TypeKind::TypeParam => { + Some((format!("{}: Non-debuggable generic", name), vec![])) + } + + TypeKind::Array(_, len) => { + // Generics are not required to implement Debug + if self.has_type_param_in_array(ctx) { + Some( + (format!("{}: Array with length {}", name, len), vec![]), + ) + } else if len < RUST_DERIVE_IN_ARRAY_LIMIT { + // The simple case + debug_print(name, quote! { #name_ident }) + } else { + // Let's implement our own print function + Some(( + format!("{}: [{{}}]", name), + vec![quote! { + self.#name_ident + .iter() + .enumerate() + .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) + .collect::() + }], + )) + } + } + + TypeKind::ResolvedTypeRef(t) | + TypeKind::TemplateAlias(t, _) | + TypeKind::Alias(t) => { + // We follow the aliases + ctx.resolve_item(t).impl_debug(ctx, name) + } + + TypeKind::Pointer(inner) => { + let inner_type = ctx.resolve_type(inner).canonical_type(ctx); + match *inner_type.kind() { + TypeKind::Function(ref sig) + if !sig.can_trivially_derive_debug() => { + Some((format!("{}: FunctionPointer", name), vec![])) + } + _ => debug_print(name, quote! { #name_ident }), + } + } + + TypeKind::Opaque => None, + } + } +} diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index ad4f65f4..8a9a5df5 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,4 +1,4 @@ -mod derive_debug; +mod impl_debug; mod error; mod helpers; pub mod struct_layout; @@ -1914,7 +1914,7 @@ impl CodeGenerator for CompInfo { } if needs_debug_impl { - let impl_ = derive_debug::gen_debug_impl( + let impl_ = impl_debug::gen_debug_impl( ctx, self.fields(), item, -- cgit v1.2.3 From 777151db7056cebe9565d6b657ca60a8c56987ee Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Fri, 22 Sep 2017 12:06:15 +0300 Subject: Fix condition in command_line_flags for impl_debug --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 10bdc6f9..0eb6bbae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -247,7 +247,7 @@ impl Builder { output_vector.push("--no-derive-debug".into()); } - if !self.options.impl_debug { + if self.options.impl_debug { output_vector.push("--impl-debug".into()); } -- cgit v1.2.3