blob: 0066003b2c0fb3cd10dbb1f66cf09f9872a90002 [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 Tolnay62f374c2016-10-02 13:37:00 -0700242 use ty::parsing::{mutability, 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 Tolnaydaaf7742016-10-03 11:11:43 -0700263 // TODO: DefaultImpl
264 // TODO: Impl
David Tolnay84aa0752016-10-02 23:01:13 -0700265 |
266 item_mac
267 ));
268
269 named!(item_mac -> Item, do_parse!(
270 attrs: many0!(outer_attr) >>
271 path: ident >>
272 punct!("!") >>
273 name: option!(ident) >>
274 body: delimited >>
275 (Item {
276 ident: name.unwrap_or_else(|| Ident::new("")),
277 vis: Visibility::Inherited,
278 attrs: attrs,
279 node: ItemKind::Mac(Mac {
280 path: path.into(),
281 tts: vec![TokenTree::Delimited(body)],
282 }),
283 })
David Tolnayedf2b992016-09-23 20:43:45 -0700284 ));
285
David Tolnaya96a3fa2016-09-24 07:17:42 -0700286 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700287 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700288 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700289 keyword!("extern") >>
290 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700291 id: ident >>
292 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700293 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700294 ident
295 )) >>
296 punct!(";") >>
297 ({
298 let (name, original_name) = match rename {
299 Some(rename) => (rename, Some(id)),
300 None => (id, None),
301 };
302 Item {
303 ident: name,
304 vis: vis,
305 attrs: attrs,
306 node: ItemKind::ExternCrate(original_name),
307 }
308 })
309 ));
310
David Tolnay47a877c2016-10-01 16:50:55 -0700311 named!(item_static -> Item, do_parse!(
312 attrs: many0!(outer_attr) >>
313 vis: visibility >>
314 keyword!("static") >>
315 mutability: mutability >>
316 id: ident >>
317 punct!(":") >>
318 ty: ty >>
319 punct!("=") >>
320 value: expr >>
321 punct!(";") >>
322 (Item {
323 ident: id,
324 vis: vis,
325 attrs: attrs,
326 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
327 })
328 ));
329
330 named!(item_const -> Item, do_parse!(
331 attrs: many0!(outer_attr) >>
332 vis: visibility >>
333 keyword!("const") >>
334 id: ident >>
335 punct!(":") >>
336 ty: ty >>
337 punct!("=") >>
338 value: expr >>
339 punct!(";") >>
340 (Item {
341 ident: id,
342 vis: vis,
343 attrs: attrs,
344 node: ItemKind::Const(Box::new(ty), Box::new(value)),
345 })
346 ));
347
David Tolnay42602292016-10-01 22:25:45 -0700348 named!(item_fn -> Item, do_parse!(
349 attrs: many0!(outer_attr) >>
350 vis: visibility >>
351 constness: constness >>
352 unsafety: unsafety >>
353 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
354 keyword!("fn") >>
355 name: ident >>
356 generics: generics >>
357 punct!("(") >>
358 inputs: separated_list!(punct!(","), fn_arg) >>
359 punct!(")") >>
360 ret: option!(preceded!(punct!("->"), ty)) >>
361 where_clause: where_clause >>
362 body: block >>
363 (Item {
364 ident: name,
365 vis: vis,
366 attrs: attrs,
367 node: ItemKind::Fn(
368 Box::new(FnDecl {
369 inputs: inputs,
370 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
371 }),
372 unsafety,
373 constness,
374 abi.map(Abi),
375 Generics {
376 where_clause: where_clause,
377 .. generics
378 },
379 Box::new(body),
380 ),
381 })
382 ));
383
David Tolnayca085422016-10-04 00:12:38 -0700384 named!(fn_arg -> FnArg, alt!(
385 do_parse!(
386 punct!("&") >>
387 lt: option!(lifetime) >>
388 mutability: mutability >>
389 keyword!("self") >>
390 (FnArg::SelfRef(lt, mutability))
391 )
392 |
393 do_parse!(
394 mutability: mutability >>
395 keyword!("self") >>
396 (FnArg::SelfValue(mutability))
397 )
398 |
399 do_parse!(
400 pat: pat >>
401 punct!(":") >>
402 ty: ty >>
403 (FnArg::Captured(pat, ty))
404 )
405 |
406 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700407 ));
408
David Tolnay3cf52982016-10-01 17:11:37 -0700409 named!(item_ty -> Item, do_parse!(
410 attrs: many0!(outer_attr) >>
411 vis: visibility >>
412 keyword!("type") >>
413 id: ident >>
414 generics: generics >>
415 punct!("=") >>
416 ty: ty >>
417 punct!(";") >>
418 (Item {
419 ident: id,
420 vis: vis,
421 attrs: attrs,
422 node: ItemKind::Ty(Box::new(ty), generics),
423 })
424 ));
425
David Tolnaya96a3fa2016-09-24 07:17:42 -0700426 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700427 macro_input,
428 |def: MacroInput| Item {
429 ident: def.ident,
430 vis: def.vis,
431 attrs: def.attrs,
432 node: match def.body {
433 Body::Enum(variants) => {
434 ItemKind::Enum(variants, def.generics)
435 }
436 Body::Struct(variant_data) => {
437 ItemKind::Struct(variant_data, def.generics)
438 }
439 }
440 }
441 ));
David Tolnay42602292016-10-01 22:25:45 -0700442
David Tolnay2f9fa632016-10-03 22:08:48 -0700443 named!(item_union -> Item, do_parse!(
444 attrs: many0!(outer_attr) >>
445 vis: visibility >>
446 keyword!("union") >>
447 id: ident >>
448 generics: generics >>
449 where_clause: where_clause >>
450 fields: struct_like_body >>
451 (Item {
452 ident: id,
453 vis: vis,
454 attrs: attrs,
455 node: ItemKind::Union(
456 VariantData::Struct(fields),
457 Generics {
458 where_clause: where_clause,
459 .. generics
460 },
461 ),
462 })
463 ));
464
David Tolnay0aecb732016-10-03 23:03:50 -0700465 named!(item_trait -> Item, do_parse!(
466 attrs: many0!(outer_attr) >>
467 vis: visibility >>
468 unsafety: unsafety >>
469 keyword!("trait") >>
470 id: ident >>
471 generics: generics >>
472 bounds: opt_vec!(preceded!(
473 punct!(":"),
474 separated_nonempty_list!(punct!("+"), ty_param_bound)
475 )) >>
476 where_clause: where_clause >>
477 punct!("{") >>
478 body: many0!(trait_item) >>
479 punct!("}") >>
480 (Item {
481 ident: id,
482 vis: vis,
483 attrs: attrs,
484 node: ItemKind::Trait(
485 unsafety,
486 Generics {
487 where_clause: where_clause,
488 .. generics
489 },
490 bounds,
491 body,
492 ),
493 })
494 ));
495
496 named!(trait_item -> TraitItem, alt!(
497 trait_item_const
498 |
499 trait_item_method
500 |
501 trait_item_type
502 |
503 trait_item_mac
504 ));
505
506 named!(trait_item_const -> TraitItem, do_parse!(
507 attrs: many0!(outer_attr) >>
508 keyword!("const") >>
509 id: ident >>
510 punct!(":") >>
511 ty: ty >>
512 value: option!(preceded!(punct!("="), expr)) >>
513 punct!(";") >>
514 (TraitItem {
515 ident: id,
516 attrs: attrs,
517 node: TraitItemKind::Const(ty, value),
518 })
519 ));
520
521 named!(trait_item_method -> TraitItem, do_parse!(
522 attrs: many0!(outer_attr) >>
523 constness: constness >>
524 unsafety: unsafety >>
525 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
526 keyword!("fn") >>
527 name: ident >>
528 generics: generics >>
529 punct!("(") >>
530 inputs: separated_list!(punct!(","), fn_arg) >>
531 punct!(")") >>
532 ret: option!(preceded!(punct!("->"), ty)) >>
533 where_clause: where_clause >>
534 body: option!(block) >>
535 cond!(body.is_none(), punct!(";")) >>
536 (TraitItem {
537 ident: name,
538 attrs: attrs,
539 node: TraitItemKind::Method(
540 MethodSig {
541 unsafety: unsafety,
542 constness: constness,
543 abi: abi.map(Abi),
544 decl: FnDecl {
545 inputs: inputs,
546 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
547 },
548 generics: Generics {
549 where_clause: where_clause,
550 .. generics
551 },
552 },
553 body,
554 ),
555 })
556 ));
557
558 named!(trait_item_type -> TraitItem, do_parse!(
559 attrs: many0!(outer_attr) >>
560 keyword!("type") >>
561 id: ident >>
562 bounds: opt_vec!(preceded!(
563 punct!(":"),
564 separated_nonempty_list!(punct!("+"), ty_param_bound)
565 )) >>
566 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700567 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700568 (TraitItem {
569 ident: id,
570 attrs: attrs,
571 node: TraitItemKind::Type(bounds, default),
572 })
573 ));
574
575 named!(trait_item_mac -> TraitItem, do_parse!(
576 attrs: many0!(outer_attr) >>
577 id: ident >>
578 punct!("!") >>
579 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700580 cond!(match body.delim {
581 DelimToken::Paren | DelimToken::Bracket => true,
582 DelimToken::Brace => false,
583 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700584 (TraitItem {
585 ident: id.clone(),
586 attrs: attrs,
587 node: TraitItemKind::Macro(Mac {
588 path: id.into(),
589 tts: vec![TokenTree::Delimited(body)],
590 }),
591 })
592 ));
593
David Tolnay42602292016-10-01 22:25:45 -0700594 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700595 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -0700596 |
597 epsilon!() => { |_| Constness::NotConst }
598 ));
599
600 named!(unsafety -> Unsafety, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700601 keyword!("unsafe") => { |_| Unsafety::Unsafe }
David Tolnay42602292016-10-01 22:25:45 -0700602 |
603 epsilon!() => { |_| Unsafety::Normal }
604 ));
David Tolnayedf2b992016-09-23 20:43:45 -0700605}
David Tolnay4a51dc72016-10-01 00:40:31 -0700606
607#[cfg(feature = "printing")]
608mod printing {
609 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -0700610 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -0700611 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -0700612 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -0700613 use quote::{Tokens, ToTokens};
614
615 impl ToTokens for Item {
616 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700617 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -0700618 match self.node {
619 ItemKind::ExternCrate(ref original) => {
620 tokens.append("extern");
621 tokens.append("crate");
622 if let Some(ref original) = *original {
623 original.to_tokens(tokens);
624 tokens.append("as");
625 }
626 self.ident.to_tokens(tokens);
627 tokens.append(";");
628 }
629 ItemKind::Use(ref _view_path) => unimplemented!(),
David Tolnay47a877c2016-10-01 16:50:55 -0700630 ItemKind::Static(ref ty, ref mutability, ref expr) => {
631 self.vis.to_tokens(tokens);
632 tokens.append("static");
633 mutability.to_tokens(tokens);
634 self.ident.to_tokens(tokens);
635 tokens.append(":");
636 ty.to_tokens(tokens);
637 tokens.append("=");
638 expr.to_tokens(tokens);
639 tokens.append(";");
640 }
641 ItemKind::Const(ref ty, ref expr) => {
642 self.vis.to_tokens(tokens);
643 tokens.append("const");
644 self.ident.to_tokens(tokens);
645 tokens.append(":");
646 ty.to_tokens(tokens);
647 tokens.append("=");
648 expr.to_tokens(tokens);
649 tokens.append(";");
650 }
David Tolnay42602292016-10-01 22:25:45 -0700651 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
652 self.vis.to_tokens(tokens);
653 constness.to_tokens(tokens);
654 unsafety.to_tokens(tokens);
655 abi.to_tokens(tokens);
656 tokens.append("fn");
657 self.ident.to_tokens(tokens);
658 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -0700659 tokens.append("(");
660 tokens.append_separated(&decl.inputs, ",");
661 tokens.append(")");
662 if let FunctionRetTy::Ty(ref ty) = decl.output {
663 tokens.append("->");
664 ty.to_tokens(tokens);
665 }
David Tolnay42602292016-10-01 22:25:45 -0700666 generics.where_clause.to_tokens(tokens);
667 block.to_tokens(tokens);
668 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700669 ItemKind::Mod(ref _items) => unimplemented!(),
670 ItemKind::ForeignMod(ref _foreign_mod) => unimplemented!(),
David Tolnay3cf52982016-10-01 17:11:37 -0700671 ItemKind::Ty(ref ty, ref generics) => {
672 self.vis.to_tokens(tokens);
673 tokens.append("type");
674 self.ident.to_tokens(tokens);
675 generics.to_tokens(tokens);
676 tokens.append("=");
677 ty.to_tokens(tokens);
678 tokens.append(";");
679 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700680 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700681 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700682 tokens.append("enum");
683 self.ident.to_tokens(tokens);
684 generics.to_tokens(tokens);
685 generics.where_clause.to_tokens(tokens);
686 tokens.append("{");
687 for variant in variants {
688 variant.to_tokens(tokens);
689 tokens.append(",");
690 }
691 tokens.append("}");
692 }
693 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700694 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700695 tokens.append("struct");
696 self.ident.to_tokens(tokens);
697 generics.to_tokens(tokens);
698 generics.where_clause.to_tokens(tokens);
699 variant_data.to_tokens(tokens);
700 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -0700701 VariantData::Struct(_) => {
702 // no semicolon
703 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700704 VariantData::Tuple(_) |
705 VariantData::Unit => tokens.append(";"),
706 }
707 }
David Tolnay2f9fa632016-10-03 22:08:48 -0700708 ItemKind::Union(ref variant_data, ref generics) => {
709 self.vis.to_tokens(tokens);
710 tokens.append("union");
711 self.ident.to_tokens(tokens);
712 generics.to_tokens(tokens);
713 generics.where_clause.to_tokens(tokens);
714 variant_data.to_tokens(tokens);
715 }
David Tolnayca085422016-10-04 00:12:38 -0700716 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
717 self.vis.to_tokens(tokens);
718 unsafety.to_tokens(tokens);
719 tokens.append("trait");
720 self.ident.to_tokens(tokens);
721 if !bound.is_empty() {
722 tokens.append(":");
723 tokens.append_separated(bound, "+");
724 }
725 generics.to_tokens(tokens);
726 generics.where_clause.to_tokens(tokens);
727 tokens.append("{");
728 tokens.append_all(items);
729 tokens.append("}");
730 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700731 ItemKind::DefaultImpl(_unsafety, ref _path) => unimplemented!(),
David Tolnaydaaf7742016-10-03 11:11:43 -0700732 ItemKind::Impl(_unsafety,
733 _polarity,
734 ref _generics,
735 ref _path,
736 ref _ty,
737 ref _item) => unimplemented!(),
David Tolnaycc3d66e2016-10-02 23:36:05 -0700738 ItemKind::Mac(ref mac) => {
739 mac.path.to_tokens(tokens);
740 tokens.append("!");
741 self.ident.to_tokens(tokens);
742 for tt in &mac.tts {
743 tt.to_tokens(tokens);
744 }
745 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -0700746 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
747 // no semicolon
748 }
David Tolnaycc3d66e2016-10-02 23:36:05 -0700749 _ => tokens.append(";"),
750 }
751 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700752 }
753 }
754 }
David Tolnay42602292016-10-01 22:25:45 -0700755
David Tolnayca085422016-10-04 00:12:38 -0700756 impl ToTokens for TraitItem {
757 fn to_tokens(&self, tokens: &mut Tokens) {
758 tokens.append_all(self.attrs.outer());
759 match self.node {
760 TraitItemKind::Const(ref ty, ref expr) => {
761 tokens.append("const");
762 self.ident.to_tokens(tokens);
763 tokens.append(":");
764 ty.to_tokens(tokens);
765 if let Some(ref expr) = *expr {
766 tokens.append("=");
767 expr.to_tokens(tokens);
768 }
769 tokens.append(";");
770 }
771 TraitItemKind::Method(ref sig, ref block) => {
772 sig.unsafety.to_tokens(tokens);
773 sig.abi.to_tokens(tokens);
774 tokens.append("fn");
775 self.ident.to_tokens(tokens);
776 sig.generics.to_tokens(tokens);
777 tokens.append("(");
778 tokens.append_separated(&sig.decl.inputs, ",");
779 tokens.append(")");
780 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
781 tokens.append("->");
782 ty.to_tokens(tokens);
783 }
784 sig.generics.where_clause.to_tokens(tokens);
785 match *block {
786 Some(ref block) => block.to_tokens(tokens),
787 None => tokens.append(";"),
788 }
789 }
790 TraitItemKind::Type(ref bound, ref default) => {
791 tokens.append("type");
792 self.ident.to_tokens(tokens);
793 if !bound.is_empty() {
794 tokens.append(":");
795 tokens.append_separated(bound, "+");
796 }
797 if let Some(ref default) = *default {
798 tokens.append("=");
799 default.to_tokens(tokens);
800 }
801 tokens.append(";");
802 }
803 TraitItemKind::Macro(ref mac) => {
804 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -0700805 match mac.tts.last() {
806 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
807 // no semicolon
808 }
809 _ => tokens.append(";"),
810 }
David Tolnayca085422016-10-04 00:12:38 -0700811 }
812 }
813 }
814 }
815
David Tolnay62f374c2016-10-02 13:37:00 -0700816 impl ToTokens for FnArg {
817 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700818 match *self {
819 FnArg::SelfRef(ref lifetime, mutability) => {
820 tokens.append("&");
821 lifetime.to_tokens(tokens);
822 mutability.to_tokens(tokens);
823 tokens.append("self");
824 }
825 FnArg::SelfValue(mutability) => {
826 mutability.to_tokens(tokens);
827 tokens.append("self");
828 }
829 FnArg::Captured(ref pat, ref ty) => {
830 pat.to_tokens(tokens);
831 tokens.append(":");
832 ty.to_tokens(tokens);
833 }
834 FnArg::Ignored(ref ty) => {
835 ty.to_tokens(tokens);
836 }
837 }
David Tolnay62f374c2016-10-02 13:37:00 -0700838 }
839 }
840
David Tolnay42602292016-10-01 22:25:45 -0700841 impl ToTokens for Unsafety {
842 fn to_tokens(&self, tokens: &mut Tokens) {
843 match *self {
844 Unsafety::Unsafe => tokens.append("unsafe"),
David Tolnaydaaf7742016-10-03 11:11:43 -0700845 Unsafety::Normal => {
846 // nothing
847 }
David Tolnay42602292016-10-01 22:25:45 -0700848 }
849 }
850 }
851
852 impl ToTokens for Constness {
853 fn to_tokens(&self, tokens: &mut Tokens) {
854 match *self {
855 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -0700856 Constness::NotConst => {
857 // nothing
858 }
David Tolnay42602292016-10-01 22:25:45 -0700859 }
860 }
861 }
862
863 impl ToTokens for Abi {
864 fn to_tokens(&self, tokens: &mut Tokens) {
865 tokens.append("extern");
866 self.0.to_tokens(tokens);
867 }
868 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700869}