Skip to content

Commit d7765b7

Browse files
author
bors-servo
authored
Auto merge of #1251 - emilio:enum-docs, r=pepyakin
codegen: expose enum variant documentation. Fixes #1250.
2 parents 079d838 + b1f9cf9 commit d7765b7

17 files changed

+309
-15
lines changed

src/codegen/mod.rs

+57-15
Original file line numberDiff line numberDiff line change
@@ -2129,36 +2129,54 @@ impl EnumVariation {
21292129
/// A helper type to construct different enum variations.
21302130
enum EnumBuilder<'a> {
21312131
Rust {
2132+
codegen_depth: usize,
21322133
attrs: Vec<quote::Tokens>,
21332134
ident: proc_macro2::Term,
21342135
tokens: quote::Tokens,
21352136
emitted_any_variants: bool,
21362137
},
21372138
Bitfield {
2139+
codegen_depth: usize,
21382140
canonical_name: &'a str,
21392141
tokens: quote::Tokens,
21402142
},
2141-
Consts(Vec<quote::Tokens>),
2143+
Consts {
2144+
variants: Vec<quote::Tokens>,
2145+
codegen_depth: usize,
2146+
},
21422147
ModuleConsts {
2148+
codegen_depth: usize,
21432149
module_name: &'a str,
21442150
module_items: Vec<quote::Tokens>,
21452151
},
21462152
}
21472153

21482154
impl<'a> EnumBuilder<'a> {
2155+
/// Returns the depth of the code generation for a variant of this enum.
2156+
fn codegen_depth(&self) -> usize {
2157+
match *self {
2158+
EnumBuilder::Rust { codegen_depth, .. } |
2159+
EnumBuilder::Bitfield { codegen_depth, .. } |
2160+
EnumBuilder::ModuleConsts { codegen_depth, .. } |
2161+
EnumBuilder::Consts { codegen_depth, .. } => codegen_depth,
2162+
}
2163+
}
2164+
21492165
/// Create a new enum given an item builder, a canonical name, a name for
21502166
/// the representation, and which variation it should be generated as.
21512167
fn new(
21522168
name: &'a str,
21532169
attrs: Vec<quote::Tokens>,
21542170
repr: quote::Tokens,
2155-
enum_variation: EnumVariation
2171+
enum_variation: EnumVariation,
2172+
enum_codegen_depth: usize,
21562173
) -> Self {
21572174
let ident = proc_macro2::Term::intern(name);
21582175

21592176
match enum_variation {
21602177
EnumVariation::Bitfield => {
21612178
EnumBuilder::Bitfield {
2179+
codegen_depth: enum_codegen_depth,
21622180
canonical_name: name,
21632181
tokens: quote! {
21642182
#( #attrs )*
@@ -2170,6 +2188,7 @@ impl<'a> EnumBuilder<'a> {
21702188
EnumVariation::Rust => {
21712189
let tokens = quote!();
21722190
EnumBuilder::Rust {
2191+
codegen_depth: enum_codegen_depth + 1,
21732192
attrs,
21742193
ident,
21752194
tokens,
@@ -2178,20 +2197,26 @@ impl<'a> EnumBuilder<'a> {
21782197
}
21792198

21802199
EnumVariation::Consts => {
2181-
EnumBuilder::Consts(vec![
2182-
quote! {
2183-
pub type #ident = #repr;
2184-
}
2185-
])
2200+
EnumBuilder::Consts {
2201+
variants: vec![
2202+
quote! {
2203+
#( #attrs )*
2204+
pub type #ident = #repr;
2205+
}
2206+
],
2207+
codegen_depth: enum_codegen_depth,
2208+
}
21862209
}
21872210

21882211
EnumVariation::ModuleConsts => {
21892212
let ident = proc_macro2::Term::intern(CONSTIFIED_ENUM_MODULE_REPR_NAME);
21902213
let type_definition = quote! {
2214+
#( #attrs )*
21912215
pub type #ident = #repr;
21922216
};
21932217

21942218
EnumBuilder::ModuleConsts {
2219+
codegen_depth: enum_codegen_depth + 1,
21952220
module_name: name,
21962221
module_items: vec![type_definition],
21972222
}
@@ -2214,14 +2239,24 @@ impl<'a> EnumBuilder<'a> {
22142239
EnumVariantValue::Unsigned(v) => helpers::ast_ty::uint_expr(v),
22152240
};
22162241

2242+
let mut doc = quote! {};
2243+
if ctx.options().generate_comments {
2244+
if let Some(raw_comment) = variant.comment() {
2245+
let comment = comment::preprocess(raw_comment, self.codegen_depth());
2246+
doc = attributes::doc(comment);
2247+
}
2248+
}
2249+
22172250
match self {
2218-
EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants: _ } => {
2251+
EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants: _, codegen_depth } => {
22192252
let name = ctx.rust_ident(variant_name);
22202253
EnumBuilder::Rust {
22212254
attrs,
22222255
ident,
2256+
codegen_depth,
22232257
tokens: quote! {
22242258
#tokens
2259+
#doc
22252260
#name = #expr,
22262261
},
22272262
emitted_any_variants: true,
@@ -2238,6 +2273,7 @@ impl<'a> EnumBuilder<'a> {
22382273

22392274
let ident = ctx.rust_ident(constant_name);
22402275
result.push(quote! {
2276+
#doc
22412277
pub const #ident : #rust_ty = #rust_ty ( #expr );
22422278
});
22432279

@@ -2256,24 +2292,28 @@ impl<'a> EnumBuilder<'a> {
22562292

22572293
let ident = ctx.rust_ident(constant_name);
22582294
result.push(quote! {
2295+
#doc
22592296
pub const #ident : #rust_ty = #expr ;
22602297
});
22612298

22622299
self
22632300
}
22642301
EnumBuilder::ModuleConsts {
2302+
codegen_depth,
22652303
module_name,
22662304
mut module_items,
22672305
} => {
22682306
let name = ctx.rust_ident(variant_name);
22692307
let ty = ctx.rust_ident(CONSTIFIED_ENUM_MODULE_REPR_NAME);
22702308
module_items.push(quote! {
2309+
#doc
22712310
pub const #name : #ty = #expr ;
22722311
});
22732312

22742313
EnumBuilder::ModuleConsts {
22752314
module_name,
22762315
module_items,
2316+
codegen_depth,
22772317
}
22782318
}
22792319
}
@@ -2286,23 +2326,24 @@ impl<'a> EnumBuilder<'a> {
22862326
result: &mut CodegenResult<'b>,
22872327
) -> quote::Tokens {
22882328
match self {
2289-
EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants } => {
2329+
EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants, .. } => {
22902330
let variants = if !emitted_any_variants {
22912331
quote!(__bindgen_cannot_repr_c_on_empty_enum = 0)
22922332
} else {
22932333
tokens
22942334
};
22952335

2296-
quote! (
2336+
quote! {
22972337
#( #attrs )*
22982338
pub enum #ident {
22992339
#variants
23002340
}
2301-
)
2341+
}
23022342
}
23032343
EnumBuilder::Bitfield {
23042344
canonical_name,
23052345
tokens,
2346+
..
23062347
} => {
23072348
let rust_ty_name = ctx.rust_ident_raw(canonical_name);
23082349
let prefix = ctx.trait_prefix();
@@ -2349,10 +2390,11 @@ impl<'a> EnumBuilder<'a> {
23492390

23502391
tokens
23512392
}
2352-
EnumBuilder::Consts(tokens) => quote! { #( #tokens )* },
2393+
EnumBuilder::Consts { variants, .. } => quote! { #( #variants )* },
23532394
EnumBuilder::ModuleConsts {
23542395
module_items,
23552396
module_name,
2397+
..
23562398
} => {
23572399
let ident = ctx.rust_ident(module_name);
23582400
quote! {
@@ -2489,7 +2531,8 @@ impl CodeGenerator for Enum {
24892531
&name,
24902532
attrs,
24912533
repr,
2492-
variation
2534+
variation,
2535+
item.codegen_depth(ctx),
24932536
);
24942537

24952538
// A map where we keep a value -> variant relation.
@@ -2522,8 +2565,7 @@ impl CodeGenerator for Enum {
25222565
let mut iter = self.variants().iter().peekable();
25232566
while let Some(variant) = iter.next().or_else(|| {
25242567
constified_variants.pop_front()
2525-
})
2526-
{
2568+
}) {
25272569
if variant.hidden() {
25282570
continue;
25292571
}

src/ir/enum_ty.rs

+5
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ impl EnumVariant {
221221
self.val
222222
}
223223

224+
/// Get this variant's documentation.
225+
pub fn comment(&self) -> Option<&str> {
226+
self.comment.as_ref().map(|s| &**s)
227+
}
228+
224229
/// Returns whether this variant should be enforced to be a constant by code
225230
/// generation.
226231
pub fn force_constification(&self) -> bool {

tests/expectations/tests/constify-enum.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ pub enum nsCSSPropertyID {
1313
eCSSProperty_b = 1,
1414
eCSSPropertyAlias_aa = 2,
1515
eCSSPropertyAlias_bb = 3,
16+
/// < <div rustbindgen constant></div>
1617
eCSSProperty_COUNT_unexistingVariantValue = 4,
1718
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
/// Document field with three slashes
6+
pub const B_VAR_A: B = B(0);
7+
/// Document field with preceeding star
8+
pub const B_VAR_B: B = B(1);
9+
/// Document field with preceeding exclamation
10+
pub const B_VAR_C: B = B(2);
11+
/// < Document field with following star
12+
pub const B_VAR_D: B = B(3);
13+
/// < Document field with following exclamation
14+
pub const B_VAR_E: B = B(4);
15+
/// Document field with preceeding star, with a loong long multiline
16+
/// comment.
17+
///
18+
/// Very interesting documentation, definitely.
19+
pub const B_VAR_F: B = B(5);
20+
impl ::std::ops::BitOr<B> for B {
21+
type Output = Self;
22+
#[inline]
23+
fn bitor(self, other: Self) -> Self {
24+
B(self.0 | other.0)
25+
}
26+
}
27+
impl ::std::ops::BitOrAssign for B {
28+
#[inline]
29+
fn bitor_assign(&mut self, rhs: B) {
30+
self.0 |= rhs.0;
31+
}
32+
}
33+
impl ::std::ops::BitAnd<B> for B {
34+
type Output = Self;
35+
#[inline]
36+
fn bitand(self, other: Self) -> Self {
37+
B(self.0 & other.0)
38+
}
39+
}
40+
impl ::std::ops::BitAndAssign for B {
41+
#[inline]
42+
fn bitand_assign(&mut self, rhs: B) {
43+
self.0 &= rhs.0;
44+
}
45+
}
46+
#[repr(C)]
47+
/// Document enum
48+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
49+
pub struct B(pub u32);
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
pub mod B {
6+
/// Document enum
7+
pub type Type = u32;
8+
/// Document field with three slashes
9+
pub const VAR_A: Type = 0;
10+
/// Document field with preceeding star
11+
pub const VAR_B: Type = 1;
12+
/// Document field with preceeding exclamation
13+
pub const VAR_C: Type = 2;
14+
/// < Document field with following star
15+
pub const VAR_D: Type = 3;
16+
/// < Document field with following exclamation
17+
pub const VAR_E: Type = 4;
18+
/// Document field with preceeding star, with a loong long multiline
19+
/// comment.
20+
///
21+
/// Very interesting documentation, definitely.
22+
pub const VAR_F: Type = 5;
23+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
#[repr(u32)]
6+
/// Document enum
7+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8+
pub enum B {
9+
/// Document field with three slashes
10+
VAR_A = 0,
11+
/// Document field with preceeding star
12+
VAR_B = 1,
13+
/// Document field with preceeding exclamation
14+
VAR_C = 2,
15+
/// < Document field with following star
16+
VAR_D = 3,
17+
/// < Document field with following exclamation
18+
VAR_E = 4,
19+
/// Document field with preceeding star, with a loong long multiline
20+
/// comment.
21+
///
22+
/// Very interesting documentation, definitely.
23+
VAR_F = 5,
24+
}

tests/expectations/tests/enum-doc.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
/// Document field with three slashes
6+
pub const B_VAR_A: B = 0;
7+
/// Document field with preceeding star
8+
pub const B_VAR_B: B = 1;
9+
/// Document field with preceeding exclamation
10+
pub const B_VAR_C: B = 2;
11+
/// < Document field with following star
12+
pub const B_VAR_D: B = 3;
13+
/// < Document field with following exclamation
14+
pub const B_VAR_E: B = 4;
15+
/// Document field with preceeding star, with a loong long multiline
16+
/// comment.
17+
///
18+
/// Very interesting documentation, definitely.
19+
pub const B_VAR_F: B = 5;
20+
/// Document enum
21+
pub type B = u32;

0 commit comments

Comments
 (0)