Allow to generate associated constants in the body of C++ structs.
Opt-in since it uses a C++17 feature, but this allow exactly the same usage in C++ and Rust, which I think is nice. This also fixes constants of transparent structs in general, since the initial version of this patch broke a test (associated constants in enums), so I added a test for that too.
This commit is contained in:
+30
-18
@@ -8,12 +8,15 @@ use std::io::{Read, Write};
|
||||
use std::path;
|
||||
|
||||
use bindgen::config::{Config, Language};
|
||||
use bindgen::ir::{Constant, Function, ItemContainer, Static};
|
||||
use bindgen::ir::{Path as BindgenPath, ItemMap, Struct, Constant, Function, ItemContainer, Static};
|
||||
use bindgen::writer::{Source, SourceWriter};
|
||||
|
||||
/// A bindings header that can be written.
|
||||
pub struct Bindings {
|
||||
config: Config,
|
||||
pub config: Config,
|
||||
/// The map from path to struct, used to lookup whether a given type is a
|
||||
/// transparent struct. This is needed to generate code for constants.
|
||||
struct_map: ItemMap<Struct>,
|
||||
globals: Vec<Static>,
|
||||
constants: Vec<Constant>,
|
||||
items: Vec<ItemContainer>,
|
||||
@@ -23,20 +26,29 @@ pub struct Bindings {
|
||||
impl Bindings {
|
||||
pub(crate) fn new(
|
||||
config: Config,
|
||||
struct_map: ItemMap<Struct>,
|
||||
constants: Vec<Constant>,
|
||||
globals: Vec<Static>,
|
||||
items: Vec<ItemContainer>,
|
||||
functions: Vec<Function>,
|
||||
) -> Bindings {
|
||||
Bindings {
|
||||
config: config,
|
||||
globals: globals,
|
||||
constants: constants,
|
||||
items: items,
|
||||
functions: functions,
|
||||
config,
|
||||
struct_map,
|
||||
globals,
|
||||
constants,
|
||||
items,
|
||||
functions,
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(emilio): What to do when the configuration doesn't match?
|
||||
pub fn struct_is_transparent(&self, path: &BindgenPath) -> bool {
|
||||
let mut any = false;
|
||||
self.struct_map.for_items(path, |s| any |= s.is_transparent);
|
||||
any
|
||||
}
|
||||
|
||||
pub fn write_to_file<P: AsRef<path::Path>>(&self, path: P) -> bool {
|
||||
// Don't compare files if we've never written this file before
|
||||
if !path.as_ref().is_file() {
|
||||
@@ -126,7 +138,7 @@ impl Bindings {
|
||||
}
|
||||
|
||||
pub fn write<F: Write>(&self, file: F) {
|
||||
let mut out = SourceWriter::new(file, &self.config);
|
||||
let mut out = SourceWriter::new(file, self);
|
||||
|
||||
if !self.config.no_includes
|
||||
|| !self.config.includes.is_empty()
|
||||
@@ -142,7 +154,7 @@ impl Bindings {
|
||||
for constant in &self.constants {
|
||||
if constant.ty.is_primitive_or_ptr_primitive() {
|
||||
out.new_line_if_not_start();
|
||||
constant.write(&self.config, &mut out);
|
||||
constant.write(&self.config, &mut out, None);
|
||||
out.new_line();
|
||||
}
|
||||
}
|
||||
@@ -158,14 +170,14 @@ impl Bindings {
|
||||
}
|
||||
|
||||
out.new_line_if_not_start();
|
||||
match item {
|
||||
&ItemContainer::Constant(..) => unreachable!(),
|
||||
&ItemContainer::Static(..) => unreachable!(),
|
||||
&ItemContainer::Enum(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::Struct(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::Union(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::OpaqueItem(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::Typedef(ref x) => x.write(&self.config, &mut out),
|
||||
match *item {
|
||||
ItemContainer::Constant(..) => unreachable!(),
|
||||
ItemContainer::Static(..) => unreachable!(),
|
||||
ItemContainer::Enum(ref x) => x.write(&self.config, &mut out),
|
||||
ItemContainer::Struct(ref x) => x.write(&self.config, &mut out),
|
||||
ItemContainer::Union(ref x) => x.write(&self.config, &mut out),
|
||||
ItemContainer::OpaqueItem(ref x) => x.write(&self.config, &mut out),
|
||||
ItemContainer::Typedef(ref x) => x.write(&self.config, &mut out),
|
||||
}
|
||||
out.new_line();
|
||||
}
|
||||
@@ -173,7 +185,7 @@ impl Bindings {
|
||||
for constant in &self.constants {
|
||||
if !constant.ty.is_primitive_or_ptr_primitive() {
|
||||
out.new_line_if_not_start();
|
||||
constant.write(&self.config, &mut out);
|
||||
constant.write(&self.config, &mut out, None);
|
||||
out.new_line();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +284,9 @@ pub struct StructConfig {
|
||||
pub derive_gt: bool,
|
||||
/// Whether to generate a greater than or equal to operator on structs with one field
|
||||
pub derive_gte: bool,
|
||||
/// Whether associated constants should be in the body. Only applicable to
|
||||
/// non-transparent structs, and in C++-only.
|
||||
pub associated_constants_in_body: bool,
|
||||
}
|
||||
|
||||
impl Default for StructConfig {
|
||||
@@ -297,6 +300,7 @@ impl Default for StructConfig {
|
||||
derive_lte: false,
|
||||
derive_gt: false,
|
||||
derive_gte: false,
|
||||
associated_constants_in_body: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+117
-75
@@ -5,6 +5,7 @@
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use std::mem;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use syn;
|
||||
|
||||
@@ -15,6 +16,7 @@ use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
|
||||
ToCondition, Type,
|
||||
Struct,
|
||||
};
|
||||
use bindgen::writer::{Source, SourceWriter};
|
||||
|
||||
@@ -27,7 +29,7 @@ pub enum Literal {
|
||||
right: Box<Literal>,
|
||||
},
|
||||
Struct {
|
||||
name: String,
|
||||
path: Path,
|
||||
export_name: String,
|
||||
fields: Vec<(String, Literal)>,
|
||||
},
|
||||
@@ -41,7 +43,7 @@ impl fmt::Display for Literal {
|
||||
write!(f, "{} {} {}", left, op, right)
|
||||
},
|
||||
Literal::Struct {
|
||||
name: _,
|
||||
path: _,
|
||||
export_name,
|
||||
fields,
|
||||
} => write!(
|
||||
@@ -62,7 +64,7 @@ impl Literal {
|
||||
pub fn rename_for_config(&mut self, config: &Config) {
|
||||
match self {
|
||||
Literal::Struct {
|
||||
name: _,
|
||||
path: _,
|
||||
ref mut export_name,
|
||||
fields,
|
||||
} => {
|
||||
@@ -161,7 +163,7 @@ impl Literal {
|
||||
field_pairs.push((key, value));
|
||||
}
|
||||
Ok(Literal::Struct {
|
||||
name: struct_name.clone(),
|
||||
path: Path::new(struct_name.clone()),
|
||||
export_name: struct_name,
|
||||
fields: field_pairs,
|
||||
})
|
||||
@@ -180,84 +182,48 @@ pub struct Constant {
|
||||
pub cfg: Option<Cfg>,
|
||||
pub annotations: AnnotationSet,
|
||||
pub documentation: Documentation,
|
||||
pub associated_to: Option<Path>,
|
||||
}
|
||||
|
||||
fn can_handle(ty: &Type, expr: &syn::Expr) -> bool {
|
||||
if ty.is_primitive_or_ptr_primitive() {
|
||||
return true;
|
||||
}
|
||||
match *expr {
|
||||
syn::Expr::Struct(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
impl Constant {
|
||||
pub fn load(
|
||||
path: Path,
|
||||
item: &syn::ItemConst,
|
||||
mod_cfg: &Option<Cfg>,
|
||||
ty: &syn::Type,
|
||||
expr: &syn::Expr,
|
||||
attrs: &[syn::Attribute],
|
||||
associated_to: Option<Path>,
|
||||
) -> Result<Constant, String> {
|
||||
let ty = Type::load(&item.ty)?;
|
||||
|
||||
if ty.is_none() {
|
||||
return Err("Cannot have a zero sized const definition.".to_owned());
|
||||
}
|
||||
|
||||
let ty = ty.unwrap();
|
||||
|
||||
if !ty.is_primitive_or_ptr_primitive()
|
||||
&& match *item.expr {
|
||||
syn::Expr::Struct(_) => false,
|
||||
_ => true,
|
||||
let ty = Type::load(ty)?;
|
||||
let ty = match ty {
|
||||
Some(ty) => ty,
|
||||
None => {
|
||||
return Err("Cannot have a zero sized const definition.".to_owned());
|
||||
}
|
||||
{
|
||||
};
|
||||
|
||||
if !can_handle(&ty, expr) {
|
||||
return Err("Unhanded const definition".to_owned());
|
||||
}
|
||||
|
||||
Ok(Constant::new(
|
||||
path,
|
||||
ty,
|
||||
Literal::load(&item.expr)?,
|
||||
Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
|
||||
AnnotationSet::load(&item.attrs)?,
|
||||
Documentation::load(&item.attrs),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn load_assoc(
|
||||
name: String,
|
||||
item: &syn::ImplItemConst,
|
||||
mod_cfg: &Option<Cfg>,
|
||||
is_transparent: bool,
|
||||
struct_path: &Path,
|
||||
) -> Result<Constant, String> {
|
||||
let ty = Type::load(&item.ty)?;
|
||||
|
||||
if ty.is_none() {
|
||||
return Err("Cannot have a zero sized const definition.".to_owned());
|
||||
}
|
||||
let ty = ty.unwrap();
|
||||
|
||||
let can_handle_const_expr = match item.expr {
|
||||
syn::Expr::Struct(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !ty.is_primitive_or_ptr_primitive() && !can_handle_const_expr {
|
||||
return Err("Unhandled const definition".to_owned());
|
||||
}
|
||||
|
||||
let expr = Literal::load(match item.expr {
|
||||
syn::Expr::Struct(syn::ExprStruct { ref fields, .. }) => {
|
||||
if is_transparent && fields.len() == 1 {
|
||||
&fields[0].expr
|
||||
} else {
|
||||
&item.expr
|
||||
}
|
||||
}
|
||||
_ => &item.expr,
|
||||
})?;
|
||||
|
||||
let full_name = Path::new(format!("{}_{}", struct_path, name));
|
||||
|
||||
Ok(Constant::new(
|
||||
full_name,
|
||||
ty,
|
||||
expr,
|
||||
Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
|
||||
AnnotationSet::load(&item.attrs)?,
|
||||
Documentation::load(&item.attrs),
|
||||
Literal::load(&expr)?,
|
||||
Cfg::append(mod_cfg, Cfg::load(attrs)),
|
||||
AnnotationSet::load(attrs)?,
|
||||
Documentation::load(attrs),
|
||||
associated_to,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -268,6 +234,7 @@ impl Constant {
|
||||
cfg: Option<Cfg>,
|
||||
annotations: AnnotationSet,
|
||||
documentation: Documentation,
|
||||
associated_to: Option<Path>,
|
||||
) -> Self {
|
||||
let export_name = path.name().to_owned();
|
||||
Self {
|
||||
@@ -278,6 +245,7 @@ impl Constant {
|
||||
cfg,
|
||||
annotations,
|
||||
documentation,
|
||||
associated_to,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,7 +280,9 @@ impl Item for Constant {
|
||||
}
|
||||
|
||||
fn rename_for_config(&mut self, config: &Config) {
|
||||
config.export.rename(&mut self.export_name);
|
||||
if self.associated_to.is_none() {
|
||||
config.export.rename(&mut self.export_name);
|
||||
}
|
||||
self.value.rename_for_config(config);
|
||||
self.ty.rename_for_config(config, &GenericParams::default()); // FIXME: should probably propagate something here
|
||||
}
|
||||
@@ -322,20 +292,92 @@ impl Item for Constant {
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for Constant {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
impl Constant {
|
||||
pub fn write_declaration<F: Write>(
|
||||
&self,
|
||||
config: &Config,
|
||||
out: &mut SourceWriter<F>,
|
||||
associated_to_struct: &Struct,
|
||||
) {
|
||||
debug_assert!(self.associated_to.is_some());
|
||||
debug_assert!(config.language == Language::Cxx);
|
||||
debug_assert!(!associated_to_struct.is_transparent);
|
||||
debug_assert!(config.structure.associated_constants_in_body);
|
||||
debug_assert!(config.constant.allow_static_const);
|
||||
|
||||
if let Type::ConstPtr(..) = self.ty {
|
||||
out.write("static ");
|
||||
} else {
|
||||
out.write("static const ");
|
||||
}
|
||||
self.ty.write(config, out);
|
||||
write!(out, " {};", self.export_name())
|
||||
}
|
||||
|
||||
pub fn write<F: Write>(
|
||||
&self,
|
||||
config: &Config,
|
||||
out: &mut SourceWriter<F>,
|
||||
associated_to_struct: Option<&Struct>,
|
||||
) {
|
||||
if let Some(assoc) = associated_to_struct {
|
||||
if assoc.is_generic() {
|
||||
return; // Not tested / implemented yet, so bail out.
|
||||
}
|
||||
}
|
||||
|
||||
let associated_to_transparent =
|
||||
associated_to_struct.map_or(false, |s| s.is_transparent);
|
||||
|
||||
let in_body = associated_to_struct.is_some() &&
|
||||
config.language == Language::Cxx &&
|
||||
config.structure.associated_constants_in_body &&
|
||||
config.constant.allow_static_const &&
|
||||
!associated_to_transparent;
|
||||
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
let name = if in_body {
|
||||
Cow::Owned(format!(
|
||||
"{}::{}",
|
||||
associated_to_struct.unwrap().export_name(),
|
||||
self.export_name(),
|
||||
))
|
||||
} else if self.associated_to.is_none() {
|
||||
Cow::Borrowed(self.export_name())
|
||||
} else {
|
||||
let associated_name = match associated_to_struct {
|
||||
Some(s) => Cow::Borrowed(s.export_name()),
|
||||
None => {
|
||||
let mut name =
|
||||
self.associated_to.as_ref().unwrap().name().to_owned();
|
||||
config.export.rename(&mut name);
|
||||
Cow::Owned(name)
|
||||
}
|
||||
};
|
||||
|
||||
Cow::Owned(format!("{}_{}", associated_name, self.export_name()))
|
||||
};
|
||||
|
||||
let value = match self.value {
|
||||
Literal::Struct { ref fields, ref path, .. } if out.bindings().struct_is_transparent(path) => {
|
||||
&fields[0].1
|
||||
}
|
||||
_ => &self.value,
|
||||
};
|
||||
|
||||
if config.constant.allow_static_const && config.language == Language::Cxx {
|
||||
out.write(if in_body { "inline " } else { "static " });
|
||||
if let Type::ConstPtr(..) = self.ty {
|
||||
out.write("static ");
|
||||
// Nothing.
|
||||
} else {
|
||||
out.write("static const ");
|
||||
out.write("const ");
|
||||
}
|
||||
self.ty.write(config, out);
|
||||
write!(out, " {} = {};", self.export_name(), self.value)
|
||||
write!(out, " {} = {};", name, value)
|
||||
} else {
|
||||
write!(out, "#define {} {}", self.export_name(), self.value)
|
||||
write!(out, "#define {} {}", name, value)
|
||||
}
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,6 @@ impl<T: Item + Clone> ItemMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn for_items<F>(&self, path: &Path, mut callback: F)
|
||||
where
|
||||
F: FnMut(&T),
|
||||
|
||||
@@ -11,7 +11,7 @@ use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
|
||||
Repr, ToCondition, Type, Typedef,
|
||||
Repr, ToCondition, Type, Typedef, Constant,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::mangle;
|
||||
@@ -37,6 +37,7 @@ pub struct Struct {
|
||||
pub cfg: Option<Cfg>,
|
||||
pub annotations: AnnotationSet,
|
||||
pub documentation: Documentation,
|
||||
pub associated_constants: Vec<Constant>,
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
@@ -45,6 +46,10 @@ impl Struct {
|
||||
!self.fields.is_empty() && self.fields.iter().all(|x| x.1.can_cmp_eq())
|
||||
}
|
||||
|
||||
pub fn add_associated_constant(&mut self, c: Constant) {
|
||||
self.associated_constants.push(c);
|
||||
}
|
||||
|
||||
pub fn load(item: &syn::ItemStruct, mod_cfg: &Option<Cfg>) -> Result<Self, String> {
|
||||
let is_transparent = match Repr::load(&item.attrs)? {
|
||||
Repr::C => false,
|
||||
@@ -118,6 +123,7 @@ impl Struct {
|
||||
cfg,
|
||||
annotations,
|
||||
documentation,
|
||||
associated_constants: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,6 +272,10 @@ impl Item for Struct {
|
||||
for field in &mut self.fields {
|
||||
reserved::escape(&mut field.0);
|
||||
}
|
||||
|
||||
for c in self.associated_constants.iter_mut() {
|
||||
c.rename_for_config(config);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
|
||||
@@ -279,6 +289,10 @@ impl Item for Struct {
|
||||
for &(_, ref ty, _) in fields {
|
||||
ty.add_dependencies_ignoring_generics(&self.generic_params, library, out);
|
||||
}
|
||||
|
||||
for c in &self.associated_constants {
|
||||
c.add_dependencies(library, out);
|
||||
}
|
||||
}
|
||||
|
||||
fn instantiate_monomorph(
|
||||
@@ -327,7 +341,12 @@ impl Source for Struct {
|
||||
annotations: self.annotations.clone(),
|
||||
documentation: self.documentation.clone(),
|
||||
};
|
||||
return typedef.write(config, out);
|
||||
typedef.write(config, out);
|
||||
for constant in &self.associated_constants {
|
||||
out.new_line();
|
||||
constant.write(config, out, Some(self));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
@@ -484,6 +503,16 @@ impl Source for Struct {
|
||||
out.write_raw_block(body);
|
||||
}
|
||||
|
||||
if config.language == Language::Cxx &&
|
||||
config.structure.associated_constants_in_body &&
|
||||
config.constant.allow_static_const
|
||||
{
|
||||
for constant in &self.associated_constants {
|
||||
out.new_line();
|
||||
constant.write_declaration(config, out, self);
|
||||
}
|
||||
}
|
||||
|
||||
if config.language == Language::C && config.style.generate_typedef() {
|
||||
out.close_brace(false);
|
||||
write!(out, " {};", self.export_name());
|
||||
@@ -491,6 +520,11 @@ impl Source for Struct {
|
||||
out.close_brace(true);
|
||||
}
|
||||
|
||||
for constant in &self.associated_constants {
|
||||
out.new_line();
|
||||
constant.write(config, out, Some(self));
|
||||
}
|
||||
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ impl Library {
|
||||
|
||||
Ok(Bindings::new(
|
||||
self.config,
|
||||
self.structs,
|
||||
constants,
|
||||
globals,
|
||||
items,
|
||||
|
||||
+24
-57
@@ -12,7 +12,7 @@ use syn;
|
||||
use bindgen::cargo::{Cargo, PackageRef};
|
||||
use bindgen::error::Error;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParams, ItemContainer,
|
||||
AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParams,
|
||||
ItemMap, OpaqueItem, Path, Static, Struct, Type, Typedef, Union,
|
||||
};
|
||||
use bindgen::utilities::{SynAbiHelpers, SynItemHelpers};
|
||||
@@ -663,40 +663,6 @@ impl Parse {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_assoc_const_of_transparent_struct(
|
||||
&self,
|
||||
const_item: &syn::ImplItemConst,
|
||||
) -> Result<bool, ()> {
|
||||
let ty = match Type::load(&const_item.ty) {
|
||||
Ok(Some(t)) => t,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let path = match ty.get_root_path() {
|
||||
Some(p) => p,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
match self.structs.get_items(&path) {
|
||||
Some(items) => {
|
||||
if items.len() != 1 {
|
||||
error!(
|
||||
"Expected one struct to match path {}, but found {}",
|
||||
path,
|
||||
items.len(),
|
||||
);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(if let ItemContainer::Struct(ref s) = items[0] {
|
||||
s.is_transparent
|
||||
} else {
|
||||
false
|
||||
})
|
||||
}
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads associated `const` declarations
|
||||
fn load_syn_assoc_consts<'a, I>(
|
||||
&mut self,
|
||||
@@ -722,12 +688,6 @@ impl Parse {
|
||||
let impl_path = ty.unwrap().get_root_path().unwrap();
|
||||
|
||||
for item in items.into_iter() {
|
||||
let is_assoc_const_of_transparent_struct =
|
||||
match self.is_assoc_const_of_transparent_struct(&item) {
|
||||
Ok(b) => b,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if crate_name != binding_crate_name {
|
||||
info!(
|
||||
"Skip {}::{} - (const's outside of the binding crate are not used).",
|
||||
@@ -736,23 +696,31 @@ impl Parse {
|
||||
continue;
|
||||
}
|
||||
|
||||
let const_name = item.ident.to_string();
|
||||
|
||||
// TODO(emilio): It'd be nice to load them as scoped constants in
|
||||
// C++ mode.
|
||||
match Constant::load_assoc(
|
||||
const_name,
|
||||
item,
|
||||
let path = Path::new(item.ident.to_string());
|
||||
match Constant::load(
|
||||
path,
|
||||
mod_cfg,
|
||||
is_assoc_const_of_transparent_struct,
|
||||
&impl_path,
|
||||
&item.ty,
|
||||
&item.expr,
|
||||
&item.attrs,
|
||||
Some(impl_path.clone()),
|
||||
) {
|
||||
Ok(constant) => {
|
||||
info!("Take {}::{}.", crate_name, &item.ident);
|
||||
|
||||
let full_name = constant.path.clone();
|
||||
if !self.constants.try_insert(constant) {
|
||||
error!("Conflicting name for constant {}", full_name);
|
||||
info!("Take {}::{}::{}.", crate_name, impl_path, &item.ident);
|
||||
let mut any = false;
|
||||
self.structs.for_items_mut(&impl_path, |item| {
|
||||
any = true;
|
||||
item.add_associated_constant(constant.clone());
|
||||
});
|
||||
// Handle associated constants to other item types that are
|
||||
// not structs like enums or such as regular constants.
|
||||
if !any && !self.constants.try_insert(constant) {
|
||||
error!(
|
||||
"Conflicting name for constant {}::{}::{}.",
|
||||
crate_name,
|
||||
impl_path,
|
||||
&item.ident,
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(msg) => {
|
||||
@@ -779,8 +747,7 @@ impl Parse {
|
||||
}
|
||||
|
||||
let path = Path::new(item.ident.to_string());
|
||||
|
||||
match Constant::load(path, item, mod_cfg) {
|
||||
match Constant::load(path, mod_cfg, &item.ty, &item.expr, &item.attrs, None) {
|
||||
Ok(constant) => {
|
||||
info!("Take {}::{}.", crate_name, &item.ident);
|
||||
|
||||
|
||||
+14
-9
@@ -6,6 +6,7 @@ use std::cmp;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
|
||||
use bindgen::Bindings;
|
||||
use bindgen::config::{Braces, Config};
|
||||
|
||||
/// A type of way to format a list.
|
||||
@@ -57,7 +58,7 @@ impl<'a, 'b, F: Write> Write for InnerWriter<'a, 'b, F> {
|
||||
/// A utility writer for generating code easier.
|
||||
pub struct SourceWriter<'a, F: Write> {
|
||||
out: F,
|
||||
config: &'a Config,
|
||||
bindings: &'a Bindings,
|
||||
spaces: Vec<usize>,
|
||||
line_started: bool,
|
||||
line_length: usize,
|
||||
@@ -67,10 +68,10 @@ pub struct SourceWriter<'a, F: Write> {
|
||||
pub type MeasureWriter<'a> = SourceWriter<'a, NullFile>;
|
||||
|
||||
impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
pub fn new(out: F, config: &'a Config) -> SourceWriter<'a, F> {
|
||||
pub fn new(out: F, bindings: &'a Bindings) -> Self {
|
||||
SourceWriter {
|
||||
out: out,
|
||||
config: config,
|
||||
out,
|
||||
bindings,
|
||||
spaces: vec![0],
|
||||
line_started: false,
|
||||
line_length: 0,
|
||||
@@ -79,6 +80,10 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bindings(&self) -> &Bindings {
|
||||
&self.bindings
|
||||
}
|
||||
|
||||
/// Takes a function that writes source and returns the maximum line length
|
||||
/// written.
|
||||
pub fn measure<T>(&self, func: T) -> usize
|
||||
@@ -87,7 +92,7 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
{
|
||||
let mut measurer = SourceWriter {
|
||||
out: NullFile,
|
||||
config: self.config,
|
||||
bindings: self.bindings,
|
||||
spaces: self.spaces.clone(),
|
||||
line_started: self.line_started,
|
||||
line_length: self.line_length,
|
||||
@@ -118,7 +123,7 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
|
||||
pub fn push_tab(&mut self) {
|
||||
let spaces =
|
||||
self.spaces() - (self.spaces() % self.config.tab_width) + self.config.tab_width;
|
||||
self.spaces() - (self.spaces() % self.bindings.config.tab_width) + self.bindings.config.tab_width;
|
||||
self.spaces.push(spaces);
|
||||
}
|
||||
|
||||
@@ -141,7 +146,7 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
}
|
||||
|
||||
pub fn open_brace(&mut self) {
|
||||
match self.config.braces {
|
||||
match self.bindings.config.braces {
|
||||
Braces::SameLine => {
|
||||
self.write(" {");
|
||||
self.push_tab();
|
||||
@@ -186,7 +191,7 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
list_type: ListType<'b>,
|
||||
) {
|
||||
for (i, ref item) in items.iter().enumerate() {
|
||||
item.write(self.config, self);
|
||||
item.write(&self.bindings.config, self);
|
||||
|
||||
match list_type {
|
||||
ListType::Join(text) => {
|
||||
@@ -209,7 +214,7 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
let align_length = self.line_length_for_align();
|
||||
self.push_set_spaces(align_length);
|
||||
for (i, ref item) in items.iter().enumerate() {
|
||||
item.write(self.config, self);
|
||||
item.write(&self.bindings.config, self);
|
||||
|
||||
match list_type {
|
||||
ListType::Join(text) => {
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define Foo_GA 10
|
||||
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
typedef struct {
|
||||
|
||||
} Foo;
|
||||
#define Foo_GA 10
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
void root(Foo x);
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
static const int32_t Foo_GA = 10;
|
||||
|
||||
static const float Foo_ZO = 3.14;
|
||||
|
||||
struct Foo {
|
||||
|
||||
};
|
||||
static const int32_t Foo_GA = 10;
|
||||
static const float Foo_ZO = 3.14;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Constants shared by multiple CSS Box Alignment properties
|
||||
* These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bits;
|
||||
} StyleAlignFlags;
|
||||
#define StyleAlignFlags_AUTO (StyleAlignFlags){ .bits = 0 }
|
||||
#define StyleAlignFlags_NORMAL (StyleAlignFlags){ .bits = 1 }
|
||||
#define StyleAlignFlags_START (StyleAlignFlags){ .bits = 1 << 1 }
|
||||
#define StyleAlignFlags_END (StyleAlignFlags){ .bits = 1 << 2 }
|
||||
#define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
void root(StyleAlignFlags flags);
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
/// Constants shared by multiple CSS Box Alignment properties
|
||||
/// These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
|
||||
struct StyleAlignFlags {
|
||||
uint8_t bits;
|
||||
static const StyleAlignFlags AUTO;
|
||||
static const StyleAlignFlags NORMAL;
|
||||
static const StyleAlignFlags START;
|
||||
static const StyleAlignFlags END;
|
||||
static const StyleAlignFlags FLEX_START;
|
||||
};
|
||||
inline const StyleAlignFlags StyleAlignFlags::AUTO = (StyleAlignFlags){ .bits = 0 };
|
||||
inline const StyleAlignFlags StyleAlignFlags::NORMAL = (StyleAlignFlags){ .bits = 1 };
|
||||
inline const StyleAlignFlags StyleAlignFlags::START = (StyleAlignFlags){ .bits = 1 << 1 };
|
||||
inline const StyleAlignFlags StyleAlignFlags::END = (StyleAlignFlags){ .bits = 1 << 2 };
|
||||
inline const StyleAlignFlags StyleAlignFlags::FLEX_START = (StyleAlignFlags){ .bits = 1 << 3 };
|
||||
|
||||
extern "C" {
|
||||
|
||||
void root(StyleAlignFlags flags);
|
||||
|
||||
} // extern "C"
|
||||
@@ -10,13 +10,10 @@
|
||||
typedef struct {
|
||||
uint8_t bits;
|
||||
} AlignFlags;
|
||||
|
||||
#define AlignFlags_AUTO (AlignFlags){ .bits = 0 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
#define AlignFlags_END (AlignFlags){ .bits = 1 << 2 }
|
||||
|
||||
#define AlignFlags_FLEX_START (AlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
void root(AlignFlags flags);
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
struct AlignFlags {
|
||||
uint8_t bits;
|
||||
};
|
||||
|
||||
static const AlignFlags AlignFlags_AUTO = (AlignFlags){ .bits = 0 };
|
||||
|
||||
static const AlignFlags AlignFlags_NORMAL = (AlignFlags){ .bits = 1 };
|
||||
static const AlignFlags AlignFlags_START = (AlignFlags){ .bits = 1 << 1 };
|
||||
static const AlignFlags AlignFlags_END = (AlignFlags){ .bits = 1 << 2 };
|
||||
|
||||
static const AlignFlags AlignFlags_FLEX_START = (AlignFlags){ .bits = 1 << 3 };
|
||||
|
||||
static const AlignFlags AlignFlags_NORMAL = (AlignFlags){ .bits = 1 };
|
||||
extern "C" {
|
||||
|
||||
static const AlignFlags AlignFlags_START = (AlignFlags){ .bits = 1 << 1 };
|
||||
void root(AlignFlags flags);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define Foo_GA 10
|
||||
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
typedef struct Foo {
|
||||
|
||||
} Foo;
|
||||
#define Foo_GA 10
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
void root(Foo x);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Constants shared by multiple CSS Box Alignment properties
|
||||
* These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
|
||||
*/
|
||||
typedef struct StyleAlignFlags {
|
||||
uint8_t bits;
|
||||
} StyleAlignFlags;
|
||||
#define StyleAlignFlags_AUTO (StyleAlignFlags){ .bits = 0 }
|
||||
#define StyleAlignFlags_NORMAL (StyleAlignFlags){ .bits = 1 }
|
||||
#define StyleAlignFlags_START (StyleAlignFlags){ .bits = 1 << 1 }
|
||||
#define StyleAlignFlags_END (StyleAlignFlags){ .bits = 1 << 2 }
|
||||
#define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
void root(StyleAlignFlags flags);
|
||||
@@ -10,13 +10,10 @@
|
||||
typedef struct AlignFlags {
|
||||
uint8_t bits;
|
||||
} AlignFlags;
|
||||
|
||||
#define AlignFlags_AUTO (AlignFlags){ .bits = 0 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
#define AlignFlags_END (AlignFlags){ .bits = 1 << 2 }
|
||||
|
||||
#define AlignFlags_FLEX_START (AlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
void root(AlignFlags flags);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t Transparent;
|
||||
|
||||
#define FOO 0
|
||||
@@ -7,9 +7,8 @@ typedef struct PREFIXFoo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
} PREFIXFoo;
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
#define PREFIXBAR (PREFIXFoo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(PREFIXFoo x);
|
||||
|
||||
@@ -7,9 +7,8 @@ typedef struct Foo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
} Foo;
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
#define BAR (Foo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(Foo x);
|
||||
|
||||
@@ -20,12 +20,10 @@ typedef DummyStruct TransparentComplexWrapper_i32;
|
||||
typedef uint32_t TransparentPrimitiveWrapper_i32;
|
||||
|
||||
typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
|
||||
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ONE 1
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
void root(TransparentComplexWrappingStructTuple a,
|
||||
TransparentPrimitiveWrappingStructTuple b,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t Transparent;
|
||||
|
||||
#define FOO 0
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
using Transparent = uint8_t;
|
||||
|
||||
static const Transparent FOO = 0;
|
||||
@@ -7,9 +7,8 @@ typedef struct {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
} PREFIXFoo;
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
#define PREFIXBAR (PREFIXFoo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(PREFIXFoo x);
|
||||
|
||||
@@ -6,11 +6,10 @@ struct PREFIXFoo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
};
|
||||
static const PREFIXFoo PREFIXFoo_FOO = (PREFIXFoo){ .a = 42, .b = 47 };
|
||||
|
||||
static const PREFIXFoo PREFIXBAR = (PREFIXFoo){ .a = 42, .b = 1337 };
|
||||
|
||||
static const PREFIXFoo PREFIXFoo_FOO = (PREFIXFoo){ .a = 42, .b = 47 };
|
||||
|
||||
extern "C" {
|
||||
|
||||
void root(PREFIXFoo x);
|
||||
|
||||
@@ -7,9 +7,8 @@ typedef struct {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
} Foo;
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
#define BAR (Foo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(Foo x);
|
||||
|
||||
@@ -6,11 +6,10 @@ struct Foo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
};
|
||||
static const Foo Foo_FOO = (Foo){ .a = 42, .b = 47 };
|
||||
|
||||
static const Foo BAR = (Foo){ .a = 42, .b = 1337 };
|
||||
|
||||
static const Foo Foo_FOO = (Foo){ .a = 42, .b = 47 };
|
||||
|
||||
extern "C" {
|
||||
|
||||
void root(Foo x);
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define Foo_GA 10
|
||||
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
struct Foo {
|
||||
|
||||
};
|
||||
#define Foo_GA 10
|
||||
#define Foo_ZO 3.14
|
||||
|
||||
void root(struct Foo x);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Constants shared by multiple CSS Box Alignment properties
|
||||
* These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
|
||||
*/
|
||||
struct StyleAlignFlags {
|
||||
uint8_t bits;
|
||||
};
|
||||
#define StyleAlignFlags_AUTO (StyleAlignFlags){ .bits = 0 }
|
||||
#define StyleAlignFlags_NORMAL (StyleAlignFlags){ .bits = 1 }
|
||||
#define StyleAlignFlags_START (StyleAlignFlags){ .bits = 1 << 1 }
|
||||
#define StyleAlignFlags_END (StyleAlignFlags){ .bits = 1 << 2 }
|
||||
#define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
void root(struct StyleAlignFlags flags);
|
||||
@@ -10,13 +10,10 @@
|
||||
struct AlignFlags {
|
||||
uint8_t bits;
|
||||
};
|
||||
|
||||
#define AlignFlags_AUTO (AlignFlags){ .bits = 0 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
#define AlignFlags_END (AlignFlags){ .bits = 1 << 2 }
|
||||
|
||||
#define AlignFlags_FLEX_START (AlignFlags){ .bits = 1 << 3 }
|
||||
|
||||
#define AlignFlags_NORMAL (AlignFlags){ .bits = 1 }
|
||||
|
||||
#define AlignFlags_START (AlignFlags){ .bits = 1 << 1 }
|
||||
void root(struct AlignFlags flags);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t Transparent;
|
||||
|
||||
#define FOO 0
|
||||
@@ -7,9 +7,8 @@ struct PREFIXFoo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
};
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
#define PREFIXBAR (PREFIXFoo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define PREFIXFoo_FOO (PREFIXFoo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(struct PREFIXFoo x);
|
||||
|
||||
@@ -7,9 +7,8 @@ struct Foo {
|
||||
int32_t a;
|
||||
uint32_t b;
|
||||
};
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
#define BAR (Foo){ .a = 42, .b = 1337 }
|
||||
|
||||
#define Foo_FOO (Foo){ .a = 42, .b = 47 }
|
||||
|
||||
void root(struct Foo x);
|
||||
|
||||
@@ -20,12 +20,10 @@ typedef struct DummyStruct TransparentComplexWrapper_i32;
|
||||
typedef uint32_t TransparentPrimitiveWrapper_i32;
|
||||
|
||||
typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
|
||||
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ONE 1
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
void root(TransparentComplexWrappingStructTuple a,
|
||||
TransparentPrimitiveWrappingStructTuple b,
|
||||
|
||||
@@ -20,12 +20,10 @@ typedef DummyStruct TransparentComplexWrapper_i32;
|
||||
typedef uint32_t TransparentPrimitiveWrapper_i32;
|
||||
|
||||
typedef uint32_t TransparentPrimitiveWithAssociatedConstants;
|
||||
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ONE 1
|
||||
|
||||
#define TransparentPrimitiveWithAssociatedConstants_ZERO 0
|
||||
#define EnumWithAssociatedConstantInImpl_TEN 10
|
||||
|
||||
void root(TransparentComplexWrappingStructTuple a,
|
||||
TransparentPrimitiveWrappingStructTuple b,
|
||||
|
||||
@@ -21,12 +21,10 @@ template<typename T>
|
||||
using TransparentPrimitiveWrapper = uint32_t;
|
||||
|
||||
using TransparentPrimitiveWithAssociatedConstants = uint32_t;
|
||||
|
||||
static const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN = 10;
|
||||
|
||||
static const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ZERO = 0;
|
||||
static const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ONE = 1;
|
||||
|
||||
static const TransparentPrimitiveWithAssociatedConstants TransparentPrimitiveWithAssociatedConstants_ZERO = 0;
|
||||
static const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN = 10;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
bitflags! {
|
||||
/// Constants shared by multiple CSS Box Alignment properties
|
||||
///
|
||||
/// These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
|
||||
#[derive(MallocSizeOf, ToComputedValue)]
|
||||
#[repr(C)]
|
||||
pub struct AlignFlags: u8 {
|
||||
/// 'auto'
|
||||
const AUTO = 0;
|
||||
/// 'normal'
|
||||
const NORMAL = 1;
|
||||
/// 'start'
|
||||
const START = 1 << 1;
|
||||
/// 'end'
|
||||
const END = 1 << 2;
|
||||
/// 'flex-start'
|
||||
const FLEX_START = 1 << 3;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn root(flags: AlignFlags) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
[struct]
|
||||
associated_constants_in_body = true
|
||||
|
||||
[export]
|
||||
prefix = "Style" # Just ensuring they play well together :)
|
||||
@@ -17,3 +17,6 @@ bitflags! {
|
||||
const FLEX_START = 1 << 3;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn root(flags: AlignFlags) {}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#[repr(transparent)]
|
||||
struct Transparent { field: u8 }
|
||||
|
||||
const FOO: Transparent = Transparent { field: 0 };
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "derive-eq"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "expand"
|
||||
version = "0.1.0"
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "expand"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "expand"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "expand"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "mod_attr"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "mod_path"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "dependency"
|
||||
version = "0.1.0"
|
||||
|
||||
Generated
+2
@@ -1,3 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
|
||||
Reference in New Issue
Block a user