blob: 5df79bb18ed7815967fceb2fd998a7f0258673cc [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnay771ecf42016-09-23 19:26:37 -07003/// An item
4///
5/// The name might be a dummy name in case of anonymous items
David Tolnayb79ee962016-09-04 09:39:20 -07006#[derive(Debug, Clone, Eq, PartialEq)]
7pub struct Item {
8 pub ident: Ident,
9 pub vis: Visibility,
10 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -070011 pub node: ItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -070012}
13
14#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -070015pub enum ItemKind {
16 /// An`extern crate` item, with optional original crate name.
17 ///
18 /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
19 ExternCrate(Option<Ident>),
20 /// A use declaration (`use` or `pub use`) item.
21 ///
22 /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
23 Use(Box<ViewPath>),
24 /// A static item (`static` or `pub static`).
25 ///
26 /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
27 Static(Box<Ty>, Mutability, Box<Expr>),
28 /// A constant item (`const` or `pub const`).
29 ///
30 /// E.g. `const FOO: i32 = 42;`
31 Const(Box<Ty>, Box<Expr>),
32 /// A function declaration (`fn` or `pub fn`).
33 ///
34 /// E.g. `fn foo(bar: usize) -> usize { .. }`
David Tolnay42602292016-10-01 22:25:45 -070035 Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
David Tolnayf38cdf62016-09-23 19:07:09 -070036 /// A module declaration (`mod` or `pub mod`).
37 ///
38 /// E.g. `mod foo;` or `mod foo { .. }`
39 Mod(Vec<Item>),
40 /// An external module (`extern` or `pub extern`).
41 ///
42 /// E.g. `extern {}` or `extern "C" {}`
43 ForeignMod(ForeignMod),
44 /// A type alias (`type` or `pub type`).
45 ///
46 /// E.g. `type Foo = Bar<u8>;`
47 Ty(Box<Ty>, Generics),
48 /// An enum definition (`enum` or `pub enum`).
49 ///
50 /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
51 Enum(Vec<Variant>, Generics),
52 /// A struct definition (`struct` or `pub struct`).
53 ///
54 /// E.g. `struct Foo<A> { x: A }`
55 Struct(VariantData, Generics),
56 /// A union definition (`union` or `pub union`).
57 ///
58 /// E.g. `union Foo<A, B> { x: A, y: B }`
59 Union(VariantData, Generics),
60 /// A Trait declaration (`trait` or `pub trait`).
61 ///
62 /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
63 Trait(Unsafety, Generics, Vec<TyParamBound>, Vec<TraitItem>),
David Tolnay0aecb732016-10-03 23:03:50 -070064 /// Default trait implementation.
David Tolnayf38cdf62016-09-23 19:07:09 -070065 ///
66 /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
67 DefaultImpl(Unsafety, Path),
68 /// An implementation.
69 ///
70 /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
71 Impl(Unsafety,
David Tolnaydaaf7742016-10-03 11:11:43 -070072 ImplPolarity,
73 Generics,
74 Option<Path>, // (optional) trait this impl implements
75 Box<Ty>, // self
76 Vec<ImplItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -070077 /// A macro invocation (which includes macro definition).
78 ///
79 /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
80 Mac(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -070081}
82
83#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -070084pub enum ViewPath {
85 /// `foo::bar::baz as quux`
86 ///
87 /// or just
88 ///
89 /// `foo::bar::baz` (with `as baz` implicitly on the right)
David Tolnayaed77b02016-09-23 20:50:31 -070090 Simple(Ident, Path),
David Tolnayf38cdf62016-09-23 19:07:09 -070091
92 /// `foo::bar::*`
David Tolnayaed77b02016-09-23 20:50:31 -070093 Glob(Path),
David Tolnayf38cdf62016-09-23 19:07:09 -070094
David Tolnayaed77b02016-09-23 20:50:31 -070095 /// `foo::bar::{a, b, c}`
David Tolnaydaaf7742016-10-03 11:11:43 -070096 List(Path, Vec<PathListItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -070097}
98
99#[derive(Debug, Clone, Eq, PartialEq)]
100pub struct PathListItem {
101 pub name: Ident,
102 /// renamed in list, e.g. `use foo::{bar as baz};`
103 pub rename: Option<Ident>,
104}
105
106#[derive(Debug, Copy, Clone, Eq, PartialEq)]
107pub enum Unsafety {
108 Unsafe,
109 Normal,
110}
111
112#[derive(Debug, Copy, Clone, Eq, PartialEq)]
113pub enum Constness {
114 Const,
115 NotConst,
116}
117
118#[derive(Debug, Copy, Clone, Eq, PartialEq)]
119pub enum Defaultness {
120 Default,
121 Final,
122}
123
124#[derive(Debug, Clone, Eq, PartialEq)]
125pub struct Abi(pub String);
126
127/// Foreign module declaration.
128///
129/// E.g. `extern { .. }` or `extern C { .. }`
130#[derive(Debug, Clone, Eq, PartialEq)]
131pub struct ForeignMod {
132 pub abi: Abi,
133 pub items: Vec<ForeignItem>,
134}
135
136#[derive(Debug, Clone, Eq, PartialEq)]
137pub struct ForeignItem {
David Tolnayb79ee962016-09-04 09:39:20 -0700138 pub ident: Ident,
139 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700140 pub node: ForeignItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -0700141 pub vis: Visibility,
David Tolnayf38cdf62016-09-23 19:07:09 -0700142}
143
David Tolnay771ecf42016-09-23 19:26:37 -0700144/// An item within an `extern` block
David Tolnayf38cdf62016-09-23 19:07:09 -0700145#[derive(Debug, Clone, Eq, PartialEq)]
146pub enum ForeignItemKind {
147 /// A foreign function
148 Fn(Box<FnDecl>, Generics),
149 /// A foreign static item (`static ext: u8`), with optional mutability
150 /// (the boolean is true when mutable)
151 Static(Box<Ty>, bool),
152}
153
154/// Represents an item declaration within a trait declaration,
155/// possibly including a default implementation. A trait item is
156/// either required (meaning it doesn't have an implementation, just a
157/// signature) or provided (meaning it has a default implementation).
158#[derive(Debug, Clone, Eq, PartialEq)]
159pub struct TraitItem {
160 pub ident: Ident,
David Tolnayb79ee962016-09-04 09:39:20 -0700161 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700162 pub node: TraitItemKind,
163}
164
165#[derive(Debug, Clone, Eq, PartialEq)]
166pub enum TraitItemKind {
167 Const(Ty, Option<Expr>),
168 Method(MethodSig, Option<Block>),
169 Type(Vec<TyParamBound>, Option<Ty>),
170 Macro(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -0700171}
172
David Tolnay55337722016-09-11 12:58:56 -0700173#[derive(Debug, Copy, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700174pub enum ImplPolarity {
175 /// `impl Trait for Type`
176 Positive,
177 /// `impl !Trait for Type`
178 Negative,
David Tolnay55337722016-09-11 12:58:56 -0700179}
180
David Tolnayf38cdf62016-09-23 19:07:09 -0700181#[derive(Debug, Clone, Eq, PartialEq)]
182pub struct ImplItem {
183 pub ident: Ident,
184 pub vis: Visibility,
185 pub defaultness: Defaultness,
186 pub attrs: Vec<Attribute>,
187 pub node: ImplItemKind,
David Tolnayf4bbbd92016-09-23 14:41:55 -0700188}
189
David Tolnayf38cdf62016-09-23 19:07:09 -0700190#[derive(Debug, Clone, Eq, PartialEq)]
191pub enum ImplItemKind {
192 Const(Ty, Expr),
193 Method(MethodSig, Block),
194 Type(Ty),
195 Macro(Mac),
David Tolnay9d8f1972016-09-04 11:58:48 -0700196}
David Tolnayd5025812016-09-04 14:21:46 -0700197
David Tolnayf38cdf62016-09-23 19:07:09 -0700198/// Represents a method's signature in a trait declaration,
199/// or in an implementation.
200#[derive(Debug, Clone, Eq, PartialEq)]
201pub struct MethodSig {
202 pub unsafety: Unsafety,
203 pub constness: Constness,
David Tolnay0aecb732016-10-03 23:03:50 -0700204 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700205 pub decl: FnDecl,
206 pub generics: Generics,
David Tolnayd5025812016-09-04 14:21:46 -0700207}
David Tolnayedf2b992016-09-23 20:43:45 -0700208
David Tolnay62f374c2016-10-02 13:37:00 -0700209/// Header (not the body) of a function declaration.
210///
211/// E.g. `fn foo(bar: baz)`
212#[derive(Debug, Clone, Eq, PartialEq)]
213pub struct FnDecl {
214 pub inputs: Vec<FnArg>,
215 pub output: FunctionRetTy,
216}
217
218/// An argument in a function header.
219///
220/// E.g. `bar: usize` as in `fn foo(bar: usize)`
221#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayca085422016-10-04 00:12:38 -0700222pub enum FnArg {
223 SelfRef(Option<Lifetime>, Mutability),
224 SelfValue(Mutability),
225 Captured(Pat, Ty),
226 Ignored(Ty),
David Tolnay62f374c2016-10-02 13:37:00 -0700227}
228
David Tolnayedf2b992016-09-23 20:43:45 -0700229#[cfg(feature = "parsing")]
230pub mod parsing {
231 use super::*;
David Tolnaye3198932016-10-04 00:21:34 -0700232 use {DelimToken, FunctionRetTy, Generics, Ident, Mac, TokenTree, VariantData, Visibility};
David Tolnay4a51dc72016-10-01 00:40:31 -0700233 use attr::parsing::outer_attr;
David Tolnay2f9fa632016-10-03 22:08:48 -0700234 use data::parsing::{struct_like_body, visibility};
David Tolnay62f374c2016-10-02 13:37:00 -0700235 use expr::parsing::{block, expr, pat};
David Tolnayca085422016-10-04 00:12:38 -0700236 use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
David Tolnayedf2b992016-09-23 20:43:45 -0700237 use ident::parsing::ident;
David Tolnay42602292016-10-01 22:25:45 -0700238 use lit::parsing::quoted_string;
David Tolnay84aa0752016-10-02 23:01:13 -0700239 use mac::parsing::delimited;
David Tolnayedf2b992016-09-23 20:43:45 -0700240 use macro_input::{Body, MacroInput};
241 use macro_input::parsing::macro_input;
David Tolnayf94e2362016-10-04 00:29:51 -0700242 use ty::parsing::{mutability, path, ty};
David Tolnayedf2b992016-09-23 20:43:45 -0700243
244 named!(pub item -> Item, alt!(
David Tolnaya96a3fa2016-09-24 07:17:42 -0700245 item_extern_crate
David Tolnaydaaf7742016-10-03 11:11:43 -0700246 // TODO: Use
David Tolnay47a877c2016-10-01 16:50:55 -0700247 |
248 item_static
249 |
250 item_const
David Tolnay42602292016-10-01 22:25:45 -0700251 |
252 item_fn
David Tolnaydaaf7742016-10-03 11:11:43 -0700253 // TODO: Mod
254 // TODO: ForeignMod
David Tolnay3cf52982016-10-01 17:11:37 -0700255 |
256 item_ty
David Tolnayedf2b992016-09-23 20:43:45 -0700257 |
David Tolnaya96a3fa2016-09-24 07:17:42 -0700258 item_struct_or_enum
David Tolnay2f9fa632016-10-03 22:08:48 -0700259 |
260 item_union
David Tolnay0aecb732016-10-03 23:03:50 -0700261 |
262 item_trait
David Tolnayf94e2362016-10-04 00:29:51 -0700263 |
264 item_default_impl
David Tolnaydaaf7742016-10-03 11:11:43 -0700265 // TODO: Impl
David Tolnay84aa0752016-10-02 23:01:13 -0700266 |
267 item_mac
268 ));
269
270 named!(item_mac -> Item, do_parse!(
271 attrs: many0!(outer_attr) >>
272 path: ident >>
273 punct!("!") >>
274 name: option!(ident) >>
275 body: delimited >>
276 (Item {
277 ident: name.unwrap_or_else(|| Ident::new("")),
278 vis: Visibility::Inherited,
279 attrs: attrs,
280 node: ItemKind::Mac(Mac {
281 path: path.into(),
282 tts: vec![TokenTree::Delimited(body)],
283 }),
284 })
David Tolnayedf2b992016-09-23 20:43:45 -0700285 ));
286
David Tolnaya96a3fa2016-09-24 07:17:42 -0700287 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700288 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700289 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700290 keyword!("extern") >>
291 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700292 id: ident >>
293 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700294 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700295 ident
296 )) >>
297 punct!(";") >>
298 ({
299 let (name, original_name) = match rename {
300 Some(rename) => (rename, Some(id)),
301 None => (id, None),
302 };
303 Item {
304 ident: name,
305 vis: vis,
306 attrs: attrs,
307 node: ItemKind::ExternCrate(original_name),
308 }
309 })
310 ));
311
David Tolnay47a877c2016-10-01 16:50:55 -0700312 named!(item_static -> Item, do_parse!(
313 attrs: many0!(outer_attr) >>
314 vis: visibility >>
315 keyword!("static") >>
316 mutability: mutability >>
317 id: ident >>
318 punct!(":") >>
319 ty: ty >>
320 punct!("=") >>
321 value: expr >>
322 punct!(";") >>
323 (Item {
324 ident: id,
325 vis: vis,
326 attrs: attrs,
327 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
328 })
329 ));
330
331 named!(item_const -> Item, do_parse!(
332 attrs: many0!(outer_attr) >>
333 vis: visibility >>
334 keyword!("const") >>
335 id: ident >>
336 punct!(":") >>
337 ty: ty >>
338 punct!("=") >>
339 value: expr >>
340 punct!(";") >>
341 (Item {
342 ident: id,
343 vis: vis,
344 attrs: attrs,
345 node: ItemKind::Const(Box::new(ty), Box::new(value)),
346 })
347 ));
348
David Tolnay42602292016-10-01 22:25:45 -0700349 named!(item_fn -> Item, do_parse!(
350 attrs: many0!(outer_attr) >>
351 vis: visibility >>
352 constness: constness >>
353 unsafety: unsafety >>
354 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
355 keyword!("fn") >>
356 name: ident >>
357 generics: generics >>
358 punct!("(") >>
359 inputs: separated_list!(punct!(","), fn_arg) >>
360 punct!(")") >>
361 ret: option!(preceded!(punct!("->"), ty)) >>
362 where_clause: where_clause >>
363 body: block >>
364 (Item {
365 ident: name,
366 vis: vis,
367 attrs: attrs,
368 node: ItemKind::Fn(
369 Box::new(FnDecl {
370 inputs: inputs,
371 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
372 }),
373 unsafety,
374 constness,
375 abi.map(Abi),
376 Generics {
377 where_clause: where_clause,
378 .. generics
379 },
380 Box::new(body),
381 ),
382 })
383 ));
384
David Tolnayca085422016-10-04 00:12:38 -0700385 named!(fn_arg -> FnArg, alt!(
386 do_parse!(
387 punct!("&") >>
388 lt: option!(lifetime) >>
389 mutability: mutability >>
390 keyword!("self") >>
391 (FnArg::SelfRef(lt, mutability))
392 )
393 |
394 do_parse!(
395 mutability: mutability >>
396 keyword!("self") >>
397 (FnArg::SelfValue(mutability))
398 )
399 |
400 do_parse!(
401 pat: pat >>
402 punct!(":") >>
403 ty: ty >>
404 (FnArg::Captured(pat, ty))
405 )
406 |
407 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700408 ));
409
David Tolnay3cf52982016-10-01 17:11:37 -0700410 named!(item_ty -> Item, do_parse!(
411 attrs: many0!(outer_attr) >>
412 vis: visibility >>
413 keyword!("type") >>
414 id: ident >>
415 generics: generics >>
416 punct!("=") >>
417 ty: ty >>
418 punct!(";") >>
419 (Item {
420 ident: id,
421 vis: vis,
422 attrs: attrs,
423 node: ItemKind::Ty(Box::new(ty), generics),
424 })
425 ));
426
David Tolnaya96a3fa2016-09-24 07:17:42 -0700427 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700428 macro_input,
429 |def: MacroInput| Item {
430 ident: def.ident,
431 vis: def.vis,
432 attrs: def.attrs,
433 node: match def.body {
434 Body::Enum(variants) => {
435 ItemKind::Enum(variants, def.generics)
436 }
437 Body::Struct(variant_data) => {
438 ItemKind::Struct(variant_data, def.generics)
439 }
440 }
441 }
442 ));
David Tolnay42602292016-10-01 22:25:45 -0700443
David Tolnay2f9fa632016-10-03 22:08:48 -0700444 named!(item_union -> Item, do_parse!(
445 attrs: many0!(outer_attr) >>
446 vis: visibility >>
447 keyword!("union") >>
448 id: ident >>
449 generics: generics >>
450 where_clause: where_clause >>
451 fields: struct_like_body >>
452 (Item {
453 ident: id,
454 vis: vis,
455 attrs: attrs,
456 node: ItemKind::Union(
457 VariantData::Struct(fields),
458 Generics {
459 where_clause: where_clause,
460 .. generics
461 },
462 ),
463 })
464 ));
465
David Tolnay0aecb732016-10-03 23:03:50 -0700466 named!(item_trait -> Item, do_parse!(
467 attrs: many0!(outer_attr) >>
468 vis: visibility >>
469 unsafety: unsafety >>
470 keyword!("trait") >>
471 id: ident >>
472 generics: generics >>
473 bounds: opt_vec!(preceded!(
474 punct!(":"),
475 separated_nonempty_list!(punct!("+"), ty_param_bound)
476 )) >>
477 where_clause: where_clause >>
478 punct!("{") >>
479 body: many0!(trait_item) >>
480 punct!("}") >>
481 (Item {
482 ident: id,
483 vis: vis,
484 attrs: attrs,
485 node: ItemKind::Trait(
486 unsafety,
487 Generics {
488 where_clause: where_clause,
489 .. generics
490 },
491 bounds,
492 body,
493 ),
494 })
495 ));
496
David Tolnayf94e2362016-10-04 00:29:51 -0700497 named!(item_default_impl -> Item, do_parse!(
498 attrs: many0!(outer_attr) >>
499 unsafety: unsafety >>
500 keyword!("impl") >>
501 path: path >>
502 keyword!("for") >>
503 punct!("..") >>
504 punct!("{") >>
505 punct!("}") >>
506 (Item {
507 ident: "".into(),
508 vis: Visibility::Inherited,
509 attrs: attrs,
510 node: ItemKind::DefaultImpl(unsafety, path),
511 })
512 ));
513
David Tolnay0aecb732016-10-03 23:03:50 -0700514 named!(trait_item -> TraitItem, alt!(
515 trait_item_const
516 |
517 trait_item_method
518 |
519 trait_item_type
520 |
521 trait_item_mac
522 ));
523
524 named!(trait_item_const -> TraitItem, do_parse!(
525 attrs: many0!(outer_attr) >>
526 keyword!("const") >>
527 id: ident >>
528 punct!(":") >>
529 ty: ty >>
530 value: option!(preceded!(punct!("="), expr)) >>
531 punct!(";") >>
532 (TraitItem {
533 ident: id,
534 attrs: attrs,
535 node: TraitItemKind::Const(ty, value),
536 })
537 ));
538
539 named!(trait_item_method -> TraitItem, do_parse!(
540 attrs: many0!(outer_attr) >>
541 constness: constness >>
542 unsafety: unsafety >>
543 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
544 keyword!("fn") >>
545 name: ident >>
546 generics: generics >>
547 punct!("(") >>
548 inputs: separated_list!(punct!(","), fn_arg) >>
549 punct!(")") >>
550 ret: option!(preceded!(punct!("->"), ty)) >>
551 where_clause: where_clause >>
552 body: option!(block) >>
553 cond!(body.is_none(), punct!(";")) >>
554 (TraitItem {
555 ident: name,
556 attrs: attrs,
557 node: TraitItemKind::Method(
558 MethodSig {
559 unsafety: unsafety,
560 constness: constness,
561 abi: abi.map(Abi),
562 decl: FnDecl {
563 inputs: inputs,
564 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
565 },
566 generics: Generics {
567 where_clause: where_clause,
568 .. generics
569 },
570 },
571 body,
572 ),
573 })
574 ));
575
576 named!(trait_item_type -> TraitItem, do_parse!(
577 attrs: many0!(outer_attr) >>
578 keyword!("type") >>
579 id: ident >>
580 bounds: opt_vec!(preceded!(
581 punct!(":"),
582 separated_nonempty_list!(punct!("+"), ty_param_bound)
583 )) >>
584 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700585 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700586 (TraitItem {
587 ident: id,
588 attrs: attrs,
589 node: TraitItemKind::Type(bounds, default),
590 })
591 ));
592
593 named!(trait_item_mac -> TraitItem, do_parse!(
594 attrs: many0!(outer_attr) >>
595 id: ident >>
596 punct!("!") >>
597 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700598 cond!(match body.delim {
599 DelimToken::Paren | DelimToken::Bracket => true,
600 DelimToken::Brace => false,
601 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700602 (TraitItem {
603 ident: id.clone(),
604 attrs: attrs,
605 node: TraitItemKind::Macro(Mac {
606 path: id.into(),
607 tts: vec![TokenTree::Delimited(body)],
608 }),
609 })
610 ));
611
David Tolnay42602292016-10-01 22:25:45 -0700612 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700613 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -0700614 |
615 epsilon!() => { |_| Constness::NotConst }
616 ));
617
618 named!(unsafety -> Unsafety, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700619 keyword!("unsafe") => { |_| Unsafety::Unsafe }
David Tolnay42602292016-10-01 22:25:45 -0700620 |
621 epsilon!() => { |_| Unsafety::Normal }
622 ));
David Tolnayedf2b992016-09-23 20:43:45 -0700623}
David Tolnay4a51dc72016-10-01 00:40:31 -0700624
625#[cfg(feature = "printing")]
626mod printing {
627 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -0700628 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -0700629 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -0700630 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -0700631 use quote::{Tokens, ToTokens};
632
633 impl ToTokens for Item {
634 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700635 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -0700636 match self.node {
637 ItemKind::ExternCrate(ref original) => {
638 tokens.append("extern");
639 tokens.append("crate");
640 if let Some(ref original) = *original {
641 original.to_tokens(tokens);
642 tokens.append("as");
643 }
644 self.ident.to_tokens(tokens);
645 tokens.append(";");
646 }
647 ItemKind::Use(ref _view_path) => unimplemented!(),
David Tolnay47a877c2016-10-01 16:50:55 -0700648 ItemKind::Static(ref ty, ref mutability, ref expr) => {
649 self.vis.to_tokens(tokens);
650 tokens.append("static");
651 mutability.to_tokens(tokens);
652 self.ident.to_tokens(tokens);
653 tokens.append(":");
654 ty.to_tokens(tokens);
655 tokens.append("=");
656 expr.to_tokens(tokens);
657 tokens.append(";");
658 }
659 ItemKind::Const(ref ty, ref expr) => {
660 self.vis.to_tokens(tokens);
661 tokens.append("const");
662 self.ident.to_tokens(tokens);
663 tokens.append(":");
664 ty.to_tokens(tokens);
665 tokens.append("=");
666 expr.to_tokens(tokens);
667 tokens.append(";");
668 }
David Tolnay42602292016-10-01 22:25:45 -0700669 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
670 self.vis.to_tokens(tokens);
671 constness.to_tokens(tokens);
672 unsafety.to_tokens(tokens);
673 abi.to_tokens(tokens);
674 tokens.append("fn");
675 self.ident.to_tokens(tokens);
676 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -0700677 tokens.append("(");
678 tokens.append_separated(&decl.inputs, ",");
679 tokens.append(")");
680 if let FunctionRetTy::Ty(ref ty) = decl.output {
681 tokens.append("->");
682 ty.to_tokens(tokens);
683 }
David Tolnay42602292016-10-01 22:25:45 -0700684 generics.where_clause.to_tokens(tokens);
685 block.to_tokens(tokens);
686 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700687 ItemKind::Mod(ref _items) => unimplemented!(),
688 ItemKind::ForeignMod(ref _foreign_mod) => unimplemented!(),
David Tolnay3cf52982016-10-01 17:11:37 -0700689 ItemKind::Ty(ref ty, ref generics) => {
690 self.vis.to_tokens(tokens);
691 tokens.append("type");
692 self.ident.to_tokens(tokens);
693 generics.to_tokens(tokens);
694 tokens.append("=");
695 ty.to_tokens(tokens);
696 tokens.append(";");
697 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700698 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700699 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700700 tokens.append("enum");
701 self.ident.to_tokens(tokens);
702 generics.to_tokens(tokens);
703 generics.where_clause.to_tokens(tokens);
704 tokens.append("{");
705 for variant in variants {
706 variant.to_tokens(tokens);
707 tokens.append(",");
708 }
709 tokens.append("}");
710 }
711 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700712 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700713 tokens.append("struct");
714 self.ident.to_tokens(tokens);
715 generics.to_tokens(tokens);
716 generics.where_clause.to_tokens(tokens);
717 variant_data.to_tokens(tokens);
718 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -0700719 VariantData::Struct(_) => {
720 // no semicolon
721 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700722 VariantData::Tuple(_) |
723 VariantData::Unit => tokens.append(";"),
724 }
725 }
David Tolnay2f9fa632016-10-03 22:08:48 -0700726 ItemKind::Union(ref variant_data, ref generics) => {
727 self.vis.to_tokens(tokens);
728 tokens.append("union");
729 self.ident.to_tokens(tokens);
730 generics.to_tokens(tokens);
731 generics.where_clause.to_tokens(tokens);
732 variant_data.to_tokens(tokens);
733 }
David Tolnayca085422016-10-04 00:12:38 -0700734 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
735 self.vis.to_tokens(tokens);
736 unsafety.to_tokens(tokens);
737 tokens.append("trait");
738 self.ident.to_tokens(tokens);
739 if !bound.is_empty() {
740 tokens.append(":");
741 tokens.append_separated(bound, "+");
742 }
743 generics.to_tokens(tokens);
744 generics.where_clause.to_tokens(tokens);
745 tokens.append("{");
746 tokens.append_all(items);
747 tokens.append("}");
748 }
David Tolnayf94e2362016-10-04 00:29:51 -0700749 ItemKind::DefaultImpl(unsafety, ref path) => {
750 unsafety.to_tokens(tokens);
751 tokens.append("impl");
752 path.to_tokens(tokens);
753 tokens.append("for");
754 tokens.append("..");
755 tokens.append("{");
756 tokens.append("}");
757 }
David Tolnaydaaf7742016-10-03 11:11:43 -0700758 ItemKind::Impl(_unsafety,
759 _polarity,
760 ref _generics,
761 ref _path,
762 ref _ty,
763 ref _item) => unimplemented!(),
David Tolnaycc3d66e2016-10-02 23:36:05 -0700764 ItemKind::Mac(ref mac) => {
765 mac.path.to_tokens(tokens);
766 tokens.append("!");
767 self.ident.to_tokens(tokens);
768 for tt in &mac.tts {
769 tt.to_tokens(tokens);
770 }
771 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -0700772 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
773 // no semicolon
774 }
David Tolnaycc3d66e2016-10-02 23:36:05 -0700775 _ => tokens.append(";"),
776 }
777 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700778 }
779 }
780 }
David Tolnay42602292016-10-01 22:25:45 -0700781
David Tolnayca085422016-10-04 00:12:38 -0700782 impl ToTokens for TraitItem {
783 fn to_tokens(&self, tokens: &mut Tokens) {
784 tokens.append_all(self.attrs.outer());
785 match self.node {
786 TraitItemKind::Const(ref ty, ref expr) => {
787 tokens.append("const");
788 self.ident.to_tokens(tokens);
789 tokens.append(":");
790 ty.to_tokens(tokens);
791 if let Some(ref expr) = *expr {
792 tokens.append("=");
793 expr.to_tokens(tokens);
794 }
795 tokens.append(";");
796 }
797 TraitItemKind::Method(ref sig, ref block) => {
798 sig.unsafety.to_tokens(tokens);
799 sig.abi.to_tokens(tokens);
800 tokens.append("fn");
801 self.ident.to_tokens(tokens);
802 sig.generics.to_tokens(tokens);
803 tokens.append("(");
804 tokens.append_separated(&sig.decl.inputs, ",");
805 tokens.append(")");
806 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
807 tokens.append("->");
808 ty.to_tokens(tokens);
809 }
810 sig.generics.where_clause.to_tokens(tokens);
811 match *block {
812 Some(ref block) => block.to_tokens(tokens),
813 None => tokens.append(";"),
814 }
815 }
816 TraitItemKind::Type(ref bound, ref default) => {
817 tokens.append("type");
818 self.ident.to_tokens(tokens);
819 if !bound.is_empty() {
820 tokens.append(":");
821 tokens.append_separated(bound, "+");
822 }
823 if let Some(ref default) = *default {
824 tokens.append("=");
825 default.to_tokens(tokens);
826 }
827 tokens.append(";");
828 }
829 TraitItemKind::Macro(ref mac) => {
830 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -0700831 match mac.tts.last() {
832 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
833 // no semicolon
834 }
835 _ => tokens.append(";"),
836 }
David Tolnayca085422016-10-04 00:12:38 -0700837 }
838 }
839 }
840 }
841
David Tolnay62f374c2016-10-02 13:37:00 -0700842 impl ToTokens for FnArg {
843 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700844 match *self {
845 FnArg::SelfRef(ref lifetime, mutability) => {
846 tokens.append("&");
847 lifetime.to_tokens(tokens);
848 mutability.to_tokens(tokens);
849 tokens.append("self");
850 }
851 FnArg::SelfValue(mutability) => {
852 mutability.to_tokens(tokens);
853 tokens.append("self");
854 }
855 FnArg::Captured(ref pat, ref ty) => {
856 pat.to_tokens(tokens);
857 tokens.append(":");
858 ty.to_tokens(tokens);
859 }
860 FnArg::Ignored(ref ty) => {
861 ty.to_tokens(tokens);
862 }
863 }
David Tolnay62f374c2016-10-02 13:37:00 -0700864 }
865 }
866
David Tolnay42602292016-10-01 22:25:45 -0700867 impl ToTokens for Unsafety {
868 fn to_tokens(&self, tokens: &mut Tokens) {
869 match *self {
870 Unsafety::Unsafe => tokens.append("unsafe"),
David Tolnaydaaf7742016-10-03 11:11:43 -0700871 Unsafety::Normal => {
872 // nothing
873 }
David Tolnay42602292016-10-01 22:25:45 -0700874 }
875 }
876 }
877
878 impl ToTokens for Constness {
879 fn to_tokens(&self, tokens: &mut Tokens) {
880 match *self {
881 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -0700882 Constness::NotConst => {
883 // nothing
884 }
David Tolnay42602292016-10-01 22:25:45 -0700885 }
886 }
887 }
888
889 impl ToTokens for Abi {
890 fn to_tokens(&self, tokens: &mut Tokens) {
891 tokens.append("extern");
892 self.0.to_tokens(tokens);
893 }
894 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700895}