blob: 4cbac330527611040cc8fa5dbcbc47cb6ad586ba [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 Tolnay9bf4af82017-01-07 11:17:46 -08006#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayb79ee962016-09-04 09:39:20 -07007pub 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
David Tolnay9bf4af82017-01-07 11:17:46 -080014#[derive(Debug, Clone, Eq, PartialEq, Hash)]
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 { .. }`
David Tolnay37d10332016-10-13 20:51:04 -070039 Mod(Option<Vec<Item>>),
David Tolnayf38cdf62016-09-23 19:07:09 -070040 /// 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
David Tolnay0e837402016-12-22 17:25:55 -050083impl From<DeriveInput> for Item {
84 fn from(input: DeriveInput) -> Item {
David Tolnay453cfd12016-10-23 11:00:14 -070085 Item {
86 ident: input.ident,
87 vis: input.vis,
88 attrs: input.attrs,
89 node: match input.body {
90 Body::Enum(variants) => ItemKind::Enum(variants, input.generics),
91 Body::Struct(variant_data) => ItemKind::Struct(variant_data, input.generics),
92 },
93 }
94 }
95}
96
David Tolnay9bf4af82017-01-07 11:17:46 -080097#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070098pub enum ViewPath {
99 /// `foo::bar::baz as quux`
100 ///
101 /// or just
102 ///
103 /// `foo::bar::baz` (with `as baz` implicitly on the right)
David Tolnay4a057422016-10-08 00:02:31 -0700104 Simple(Path, Option<Ident>),
David Tolnayf38cdf62016-09-23 19:07:09 -0700105
106 /// `foo::bar::*`
David Tolnayaed77b02016-09-23 20:50:31 -0700107 Glob(Path),
David Tolnayf38cdf62016-09-23 19:07:09 -0700108
David Tolnayaed77b02016-09-23 20:50:31 -0700109 /// `foo::bar::{a, b, c}`
David Tolnaydaaf7742016-10-03 11:11:43 -0700110 List(Path, Vec<PathListItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -0700111}
112
David Tolnay9bf4af82017-01-07 11:17:46 -0800113#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700114pub struct PathListItem {
115 pub name: Ident,
116 /// renamed in list, e.g. `use foo::{bar as baz};`
117 pub rename: Option<Ident>,
118}
119
David Tolnay9bf4af82017-01-07 11:17:46 -0800120#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700121pub enum Constness {
122 Const,
123 NotConst,
124}
125
David Tolnay9bf4af82017-01-07 11:17:46 -0800126#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700127pub enum Defaultness {
128 Default,
129 Final,
130}
131
David Tolnayf38cdf62016-09-23 19:07:09 -0700132/// Foreign module declaration.
133///
David Tolnay35902302016-10-06 01:11:08 -0700134/// E.g. `extern { .. }` or `extern "C" { .. }`
David Tolnay9bf4af82017-01-07 11:17:46 -0800135#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700136pub struct ForeignMod {
David Tolnayb8d8ef52016-10-29 14:30:08 -0700137 pub abi: Abi,
David Tolnayf38cdf62016-09-23 19:07:09 -0700138 pub items: Vec<ForeignItem>,
139}
140
David Tolnay9bf4af82017-01-07 11:17:46 -0800141#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700142pub struct ForeignItem {
David Tolnayb79ee962016-09-04 09:39:20 -0700143 pub ident: Ident,
144 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700145 pub node: ForeignItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -0700146 pub vis: Visibility,
David Tolnayf38cdf62016-09-23 19:07:09 -0700147}
148
David Tolnay771ecf42016-09-23 19:26:37 -0700149/// An item within an `extern` block
David Tolnay9bf4af82017-01-07 11:17:46 -0800150#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700151pub enum ForeignItemKind {
152 /// A foreign function
153 Fn(Box<FnDecl>, Generics),
David Tolnay35902302016-10-06 01:11:08 -0700154 /// A foreign static item (`static ext: u8`)
155 Static(Box<Ty>, Mutability),
David Tolnayf38cdf62016-09-23 19:07:09 -0700156}
157
158/// Represents an item declaration within a trait declaration,
159/// possibly including a default implementation. A trait item is
160/// either required (meaning it doesn't have an implementation, just a
161/// signature) or provided (meaning it has a default implementation).
David Tolnay9bf4af82017-01-07 11:17:46 -0800162#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700163pub struct TraitItem {
164 pub ident: Ident,
David Tolnayb79ee962016-09-04 09:39:20 -0700165 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700166 pub node: TraitItemKind,
167}
168
David Tolnay9bf4af82017-01-07 11:17:46 -0800169#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700170pub enum TraitItemKind {
171 Const(Ty, Option<Expr>),
172 Method(MethodSig, Option<Block>),
173 Type(Vec<TyParamBound>, Option<Ty>),
174 Macro(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -0700175}
176
David Tolnay9bf4af82017-01-07 11:17:46 -0800177#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700178pub enum ImplPolarity {
179 /// `impl Trait for Type`
180 Positive,
181 /// `impl !Trait for Type`
182 Negative,
David Tolnay55337722016-09-11 12:58:56 -0700183}
184
David Tolnay9bf4af82017-01-07 11:17:46 -0800185#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700186pub struct ImplItem {
187 pub ident: Ident,
188 pub vis: Visibility,
189 pub defaultness: Defaultness,
190 pub attrs: Vec<Attribute>,
191 pub node: ImplItemKind,
David Tolnayf4bbbd92016-09-23 14:41:55 -0700192}
193
David Tolnay9bf4af82017-01-07 11:17:46 -0800194#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700195pub enum ImplItemKind {
196 Const(Ty, Expr),
197 Method(MethodSig, Block),
198 Type(Ty),
199 Macro(Mac),
David Tolnay9d8f1972016-09-04 11:58:48 -0700200}
David Tolnayd5025812016-09-04 14:21:46 -0700201
David Tolnayf38cdf62016-09-23 19:07:09 -0700202/// Represents a method's signature in a trait declaration,
203/// or in an implementation.
David Tolnay9bf4af82017-01-07 11:17:46 -0800204#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700205pub struct MethodSig {
206 pub unsafety: Unsafety,
207 pub constness: Constness,
David Tolnay0aecb732016-10-03 23:03:50 -0700208 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700209 pub decl: FnDecl,
210 pub generics: Generics,
David Tolnayd5025812016-09-04 14:21:46 -0700211}
David Tolnayedf2b992016-09-23 20:43:45 -0700212
David Tolnay62f374c2016-10-02 13:37:00 -0700213/// Header (not the body) of a function declaration.
214///
215/// E.g. `fn foo(bar: baz)`
David Tolnay9bf4af82017-01-07 11:17:46 -0800216#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnay62f374c2016-10-02 13:37:00 -0700217pub struct FnDecl {
218 pub inputs: Vec<FnArg>,
219 pub output: FunctionRetTy,
David Tolnay292e6002016-10-29 22:03:51 -0700220 pub variadic: bool,
David Tolnay62f374c2016-10-02 13:37:00 -0700221}
222
223/// An argument in a function header.
224///
225/// E.g. `bar: usize` as in `fn foo(bar: usize)`
David Tolnay9bf4af82017-01-07 11:17:46 -0800226#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayca085422016-10-04 00:12:38 -0700227pub enum FnArg {
228 SelfRef(Option<Lifetime>, Mutability),
229 SelfValue(Mutability),
230 Captured(Pat, Ty),
231 Ignored(Ty),
David Tolnay62f374c2016-10-02 13:37:00 -0700232}
233
David Tolnayedf2b992016-09-23 20:43:45 -0700234#[cfg(feature = "parsing")]
235pub mod parsing {
236 use super::*;
David Tolnay3b9783a2016-10-29 22:37:09 -0700237 use {Block, DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData,
238 Visibility};
David Tolnay7b8009b2016-10-25 22:36:00 -0700239 use attr::parsing::{inner_attr, outer_attr};
David Tolnay2f9fa632016-10-03 22:08:48 -0700240 use data::parsing::{struct_like_body, visibility};
David Tolnay5859df12016-10-29 22:49:54 -0700241 use expr::parsing::{expr, pat, within_block};
David Tolnayca085422016-10-04 00:12:38 -0700242 use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
David Tolnayedf2b992016-09-23 20:43:45 -0700243 use ident::parsing::ident;
David Tolnay84aa0752016-10-02 23:01:13 -0700244 use mac::parsing::delimited;
David Tolnay0e837402016-12-22 17:25:55 -0500245 use derive::{Body, DeriveInput};
246 use derive::parsing::derive_input;
David Tolnayb8d8ef52016-10-29 14:30:08 -0700247 use ty::parsing::{abi, mutability, path, ty, unsafety};
David Tolnayedf2b992016-09-23 20:43:45 -0700248
249 named!(pub item -> Item, alt!(
David Tolnaya96a3fa2016-09-24 07:17:42 -0700250 item_extern_crate
David Tolnay4a057422016-10-08 00:02:31 -0700251 |
252 item_use
David Tolnay47a877c2016-10-01 16:50:55 -0700253 |
254 item_static
255 |
256 item_const
David Tolnay42602292016-10-01 22:25:45 -0700257 |
258 item_fn
David Tolnay35902302016-10-06 01:11:08 -0700259 |
260 item_mod
261 |
262 item_foreign_mod
David Tolnay3cf52982016-10-01 17:11:37 -0700263 |
264 item_ty
David Tolnayedf2b992016-09-23 20:43:45 -0700265 |
David Tolnaya96a3fa2016-09-24 07:17:42 -0700266 item_struct_or_enum
David Tolnay2f9fa632016-10-03 22:08:48 -0700267 |
268 item_union
David Tolnay0aecb732016-10-03 23:03:50 -0700269 |
270 item_trait
David Tolnayf94e2362016-10-04 00:29:51 -0700271 |
272 item_default_impl
David Tolnay4c9be372016-10-06 00:47:37 -0700273 |
274 item_impl
David Tolnay84aa0752016-10-02 23:01:13 -0700275 |
276 item_mac
277 ));
278
David Tolnay453cfd12016-10-23 11:00:14 -0700279 named!(pub items -> Vec<Item>, many0!(item));
280
David Tolnay84aa0752016-10-02 23:01:13 -0700281 named!(item_mac -> Item, do_parse!(
282 attrs: many0!(outer_attr) >>
David Tolnay5d55ef72016-12-21 20:20:04 -0500283 what: path >>
David Tolnay84aa0752016-10-02 23:01:13 -0700284 punct!("!") >>
285 name: option!(ident) >>
286 body: delimited >>
David Tolnay1a8b3522016-10-08 22:27:00 -0700287 cond!(match body.delim {
288 DelimToken::Paren | DelimToken::Bracket => true,
289 DelimToken::Brace => false,
290 }, punct!(";")) >>
David Tolnay84aa0752016-10-02 23:01:13 -0700291 (Item {
292 ident: name.unwrap_or_else(|| Ident::new("")),
293 vis: Visibility::Inherited,
294 attrs: attrs,
295 node: ItemKind::Mac(Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -0500296 path: what,
David Tolnay84aa0752016-10-02 23:01:13 -0700297 tts: vec![TokenTree::Delimited(body)],
298 }),
299 })
David Tolnayedf2b992016-09-23 20:43:45 -0700300 ));
301
David Tolnaya96a3fa2016-09-24 07:17:42 -0700302 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700303 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700304 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700305 keyword!("extern") >>
306 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700307 id: ident >>
308 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700309 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700310 ident
311 )) >>
312 punct!(";") >>
313 ({
314 let (name, original_name) = match rename {
315 Some(rename) => (rename, Some(id)),
316 None => (id, None),
317 };
318 Item {
319 ident: name,
320 vis: vis,
321 attrs: attrs,
322 node: ItemKind::ExternCrate(original_name),
323 }
324 })
325 ));
326
David Tolnay4a057422016-10-08 00:02:31 -0700327 named!(item_use -> Item, do_parse!(
328 attrs: many0!(outer_attr) >>
329 vis: visibility >>
330 keyword!("use") >>
331 what: view_path >>
332 punct!(";") >>
333 (Item {
334 ident: "".into(),
335 vis: vis,
336 attrs: attrs,
337 node: ItemKind::Use(Box::new(what)),
338 })
339 ));
340
341 named!(view_path -> ViewPath, alt!(
342 view_path_glob
343 |
344 view_path_list
345 |
346 view_path_list_root
347 |
348 view_path_simple // must be last
349 ));
350
351
352 named!(view_path_simple -> ViewPath, do_parse!(
353 path: path >>
354 rename: option!(preceded!(keyword!("as"), ident)) >>
355 (ViewPath::Simple(path, rename))
356 ));
357
358 named!(view_path_glob -> ViewPath, do_parse!(
359 path: path >>
360 punct!("::") >>
361 punct!("*") >>
362 (ViewPath::Glob(path))
363 ));
364
365 named!(view_path_list -> ViewPath, do_parse!(
366 path: path >>
367 punct!("::") >>
368 punct!("{") >>
David Tolnayaab03bf2016-10-30 13:26:07 -0700369 items: terminated_list!(punct!(","), path_list_item) >>
David Tolnay4a057422016-10-08 00:02:31 -0700370 punct!("}") >>
371 (ViewPath::List(path, items))
372 ));
373
374 named!(view_path_list_root -> ViewPath, do_parse!(
375 global: option!(punct!("::")) >>
376 punct!("{") >>
David Tolnayaab03bf2016-10-30 13:26:07 -0700377 items: terminated_list!(punct!(","), path_list_item) >>
David Tolnay4a057422016-10-08 00:02:31 -0700378 punct!("}") >>
379 (ViewPath::List(Path {
380 global: global.is_some(),
381 segments: Vec::new(),
382 }, items))
383 ));
384
385 named!(path_list_item -> PathListItem, do_parse!(
David Tolnaye6e42542016-10-24 22:37:11 -0700386 name: alt!(
387 ident
388 |
389 map!(keyword!("self"), Into::into)
390 ) >>
David Tolnay4a057422016-10-08 00:02:31 -0700391 rename: option!(preceded!(keyword!("as"), ident)) >>
392 (PathListItem {
393 name: name,
394 rename: rename,
395 })
396 ));
397
David Tolnay47a877c2016-10-01 16:50:55 -0700398 named!(item_static -> Item, do_parse!(
399 attrs: many0!(outer_attr) >>
400 vis: visibility >>
401 keyword!("static") >>
402 mutability: mutability >>
403 id: ident >>
404 punct!(":") >>
405 ty: ty >>
406 punct!("=") >>
407 value: expr >>
408 punct!(";") >>
409 (Item {
410 ident: id,
411 vis: vis,
412 attrs: attrs,
413 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
414 })
415 ));
416
417 named!(item_const -> Item, do_parse!(
418 attrs: many0!(outer_attr) >>
419 vis: visibility >>
420 keyword!("const") >>
421 id: ident >>
422 punct!(":") >>
423 ty: ty >>
424 punct!("=") >>
425 value: expr >>
426 punct!(";") >>
427 (Item {
428 ident: id,
429 vis: vis,
430 attrs: attrs,
431 node: ItemKind::Const(Box::new(ty), Box::new(value)),
432 })
433 ));
434
David Tolnay42602292016-10-01 22:25:45 -0700435 named!(item_fn -> Item, do_parse!(
David Tolnay3b9783a2016-10-29 22:37:09 -0700436 outer_attrs: many0!(outer_attr) >>
David Tolnay42602292016-10-01 22:25:45 -0700437 vis: visibility >>
438 constness: constness >>
439 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700440 abi: option!(abi) >>
David Tolnay42602292016-10-01 22:25:45 -0700441 keyword!("fn") >>
442 name: ident >>
443 generics: generics >>
444 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700445 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay42602292016-10-01 22:25:45 -0700446 punct!(")") >>
447 ret: option!(preceded!(punct!("->"), ty)) >>
448 where_clause: where_clause >>
David Tolnay3b9783a2016-10-29 22:37:09 -0700449 punct!("{") >>
450 inner_attrs: many0!(inner_attr) >>
451 stmts: within_block >>
452 punct!("}") >>
David Tolnay42602292016-10-01 22:25:45 -0700453 (Item {
454 ident: name,
455 vis: vis,
David Tolnay3b9783a2016-10-29 22:37:09 -0700456 attrs: {
457 let mut attrs = outer_attrs;
458 attrs.extend(inner_attrs);
459 attrs
460 },
David Tolnay42602292016-10-01 22:25:45 -0700461 node: ItemKind::Fn(
462 Box::new(FnDecl {
463 inputs: inputs,
464 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700465 variadic: false,
David Tolnay42602292016-10-01 22:25:45 -0700466 }),
467 unsafety,
468 constness,
David Tolnayb8d8ef52016-10-29 14:30:08 -0700469 abi,
David Tolnay42602292016-10-01 22:25:45 -0700470 Generics {
471 where_clause: where_clause,
472 .. generics
473 },
David Tolnay3b9783a2016-10-29 22:37:09 -0700474 Box::new(Block {
475 stmts: stmts,
476 }),
David Tolnay42602292016-10-01 22:25:45 -0700477 ),
478 })
479 ));
480
David Tolnayca085422016-10-04 00:12:38 -0700481 named!(fn_arg -> FnArg, alt!(
482 do_parse!(
483 punct!("&") >>
484 lt: option!(lifetime) >>
485 mutability: mutability >>
486 keyword!("self") >>
David Tolnay1f16b602017-02-07 20:06:55 -0500487 not!(punct!(":")) >>
David Tolnayca085422016-10-04 00:12:38 -0700488 (FnArg::SelfRef(lt, mutability))
489 )
490 |
491 do_parse!(
492 mutability: mutability >>
493 keyword!("self") >>
David Tolnay1f16b602017-02-07 20:06:55 -0500494 not!(punct!(":")) >>
David Tolnayca085422016-10-04 00:12:38 -0700495 (FnArg::SelfValue(mutability))
496 )
497 |
498 do_parse!(
499 pat: pat >>
500 punct!(":") >>
501 ty: ty >>
502 (FnArg::Captured(pat, ty))
503 )
504 |
505 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700506 ));
507
David Tolnay35902302016-10-06 01:11:08 -0700508 named!(item_mod -> Item, do_parse!(
David Tolnay7b8009b2016-10-25 22:36:00 -0700509 outer_attrs: many0!(outer_attr) >>
David Tolnay35902302016-10-06 01:11:08 -0700510 vis: visibility >>
511 keyword!("mod") >>
512 id: ident >>
David Tolnay7b8009b2016-10-25 22:36:00 -0700513 content: alt!(
David Tolnay37d10332016-10-13 20:51:04 -0700514 punct!(";") => { |_| None }
515 |
David Tolnay7b8009b2016-10-25 22:36:00 -0700516 delimited!(
517 punct!("{"),
518 tuple!(
519 many0!(inner_attr),
520 items
521 ),
522 punct!("}")
523 ) => { Some }
David Tolnay37d10332016-10-13 20:51:04 -0700524 ) >>
David Tolnay7b8009b2016-10-25 22:36:00 -0700525 (match content {
526 Some((inner_attrs, items)) => Item {
527 ident: id,
528 vis: vis,
529 attrs: {
530 let mut attrs = outer_attrs;
531 attrs.extend(inner_attrs);
532 attrs
533 },
534 node: ItemKind::Mod(Some(items)),
535 },
536 None => Item {
537 ident: id,
538 vis: vis,
539 attrs: outer_attrs,
540 node: ItemKind::Mod(None),
541 },
David Tolnay35902302016-10-06 01:11:08 -0700542 })
543 ));
544
545 named!(item_foreign_mod -> Item, do_parse!(
546 attrs: many0!(outer_attr) >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700547 abi: abi >>
David Tolnay35902302016-10-06 01:11:08 -0700548 punct!("{") >>
549 items: many0!(foreign_item) >>
550 punct!("}") >>
551 (Item {
552 ident: "".into(),
553 vis: Visibility::Inherited,
554 attrs: attrs,
555 node: ItemKind::ForeignMod(ForeignMod {
David Tolnayb8d8ef52016-10-29 14:30:08 -0700556 abi: abi,
David Tolnay35902302016-10-06 01:11:08 -0700557 items: items,
558 }),
559 })
560 ));
561
562 named!(foreign_item -> ForeignItem, alt!(
563 foreign_fn
564 |
565 foreign_static
566 ));
567
568 named!(foreign_fn -> ForeignItem, do_parse!(
569 attrs: many0!(outer_attr) >>
570 vis: visibility >>
571 keyword!("fn") >>
572 name: ident >>
573 generics: generics >>
574 punct!("(") >>
David Tolnay292e6002016-10-29 22:03:51 -0700575 inputs: separated_list!(punct!(","), fn_arg) >>
576 trailing_comma: option!(punct!(",")) >>
577 variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
David Tolnay35902302016-10-06 01:11:08 -0700578 punct!(")") >>
579 ret: option!(preceded!(punct!("->"), ty)) >>
580 where_clause: where_clause >>
581 punct!(";") >>
582 (ForeignItem {
583 ident: name,
584 attrs: attrs,
585 node: ForeignItemKind::Fn(
586 Box::new(FnDecl {
587 inputs: inputs,
588 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700589 variadic: variadic.is_some(),
David Tolnay35902302016-10-06 01:11:08 -0700590 }),
591 Generics {
592 where_clause: where_clause,
593 .. generics
594 },
595 ),
596 vis: vis,
597 })
598 ));
599
600 named!(foreign_static -> ForeignItem, do_parse!(
601 attrs: many0!(outer_attr) >>
602 vis: visibility >>
603 keyword!("static") >>
604 mutability: mutability >>
605 id: ident >>
606 punct!(":") >>
607 ty: ty >>
608 punct!(";") >>
609 (ForeignItem {
610 ident: id,
611 attrs: attrs,
612 node: ForeignItemKind::Static(Box::new(ty), mutability),
613 vis: vis,
614 })
615 ));
616
David Tolnay3cf52982016-10-01 17:11:37 -0700617 named!(item_ty -> Item, do_parse!(
618 attrs: many0!(outer_attr) >>
619 vis: visibility >>
620 keyword!("type") >>
621 id: ident >>
622 generics: generics >>
David Tolnay04bb3ad2016-10-30 10:59:01 -0700623 where_clause: where_clause >>
David Tolnay3cf52982016-10-01 17:11:37 -0700624 punct!("=") >>
625 ty: ty >>
626 punct!(";") >>
627 (Item {
628 ident: id,
629 vis: vis,
630 attrs: attrs,
David Tolnay04bb3ad2016-10-30 10:59:01 -0700631 node: ItemKind::Ty(
632 Box::new(ty),
633 Generics {
634 where_clause: where_clause,
635 ..generics
636 },
637 ),
David Tolnay3cf52982016-10-01 17:11:37 -0700638 })
639 ));
640
David Tolnaya96a3fa2016-09-24 07:17:42 -0700641 named!(item_struct_or_enum -> Item, map!(
David Tolnay0e837402016-12-22 17:25:55 -0500642 derive_input,
643 |def: DeriveInput| Item {
David Tolnayedf2b992016-09-23 20:43:45 -0700644 ident: def.ident,
645 vis: def.vis,
646 attrs: def.attrs,
647 node: match def.body {
648 Body::Enum(variants) => {
649 ItemKind::Enum(variants, def.generics)
650 }
651 Body::Struct(variant_data) => {
652 ItemKind::Struct(variant_data, def.generics)
653 }
654 }
655 }
656 ));
David Tolnay42602292016-10-01 22:25:45 -0700657
David Tolnay2f9fa632016-10-03 22:08:48 -0700658 named!(item_union -> Item, do_parse!(
659 attrs: many0!(outer_attr) >>
660 vis: visibility >>
661 keyword!("union") >>
662 id: ident >>
663 generics: generics >>
664 where_clause: where_clause >>
665 fields: struct_like_body >>
666 (Item {
667 ident: id,
668 vis: vis,
669 attrs: attrs,
670 node: ItemKind::Union(
671 VariantData::Struct(fields),
672 Generics {
673 where_clause: where_clause,
674 .. generics
675 },
676 ),
677 })
678 ));
679
David Tolnay0aecb732016-10-03 23:03:50 -0700680 named!(item_trait -> Item, do_parse!(
681 attrs: many0!(outer_attr) >>
682 vis: visibility >>
683 unsafety: unsafety >>
684 keyword!("trait") >>
685 id: ident >>
686 generics: generics >>
687 bounds: opt_vec!(preceded!(
688 punct!(":"),
689 separated_nonempty_list!(punct!("+"), ty_param_bound)
690 )) >>
691 where_clause: where_clause >>
692 punct!("{") >>
693 body: many0!(trait_item) >>
694 punct!("}") >>
695 (Item {
696 ident: id,
697 vis: vis,
698 attrs: attrs,
699 node: ItemKind::Trait(
700 unsafety,
701 Generics {
702 where_clause: where_clause,
703 .. generics
704 },
705 bounds,
706 body,
707 ),
708 })
709 ));
710
David Tolnayf94e2362016-10-04 00:29:51 -0700711 named!(item_default_impl -> Item, do_parse!(
712 attrs: many0!(outer_attr) >>
713 unsafety: unsafety >>
714 keyword!("impl") >>
715 path: path >>
716 keyword!("for") >>
717 punct!("..") >>
718 punct!("{") >>
719 punct!("}") >>
720 (Item {
721 ident: "".into(),
722 vis: Visibility::Inherited,
723 attrs: attrs,
724 node: ItemKind::DefaultImpl(unsafety, path),
725 })
726 ));
727
David Tolnay0aecb732016-10-03 23:03:50 -0700728 named!(trait_item -> TraitItem, alt!(
729 trait_item_const
730 |
731 trait_item_method
732 |
733 trait_item_type
734 |
735 trait_item_mac
736 ));
737
738 named!(trait_item_const -> TraitItem, do_parse!(
739 attrs: many0!(outer_attr) >>
740 keyword!("const") >>
741 id: ident >>
742 punct!(":") >>
743 ty: ty >>
744 value: option!(preceded!(punct!("="), expr)) >>
745 punct!(";") >>
746 (TraitItem {
747 ident: id,
748 attrs: attrs,
749 node: TraitItemKind::Const(ty, value),
750 })
751 ));
752
753 named!(trait_item_method -> TraitItem, do_parse!(
David Tolnay5859df12016-10-29 22:49:54 -0700754 outer_attrs: many0!(outer_attr) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700755 constness: constness >>
756 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700757 abi: option!(abi) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700758 keyword!("fn") >>
759 name: ident >>
760 generics: generics >>
761 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700762 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700763 punct!(")") >>
764 ret: option!(preceded!(punct!("->"), ty)) >>
765 where_clause: where_clause >>
David Tolnay5859df12016-10-29 22:49:54 -0700766 body: option!(delimited!(
767 punct!("{"),
768 tuple!(many0!(inner_attr), within_block),
769 punct!("}")
770 )) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700771 cond!(body.is_none(), punct!(";")) >>
David Tolnay5859df12016-10-29 22:49:54 -0700772 ({
773 let (inner_attrs, stmts) = match body {
774 Some((inner_attrs, stmts)) => (inner_attrs, Some(stmts)),
775 None => (Vec::new(), None),
776 };
777 TraitItem {
778 ident: name,
779 attrs: {
780 let mut attrs = outer_attrs;
781 attrs.extend(inner_attrs);
782 attrs
David Tolnay0aecb732016-10-03 23:03:50 -0700783 },
David Tolnay5859df12016-10-29 22:49:54 -0700784 node: TraitItemKind::Method(
785 MethodSig {
786 unsafety: unsafety,
787 constness: constness,
788 abi: abi,
789 decl: FnDecl {
790 inputs: inputs,
791 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
792 variadic: false,
793 },
794 generics: Generics {
795 where_clause: where_clause,
796 .. generics
797 },
798 },
799 stmts.map(|stmts| Block { stmts: stmts }),
800 ),
801 }
David Tolnay0aecb732016-10-03 23:03:50 -0700802 })
803 ));
804
805 named!(trait_item_type -> TraitItem, do_parse!(
806 attrs: many0!(outer_attr) >>
807 keyword!("type") >>
808 id: ident >>
809 bounds: opt_vec!(preceded!(
810 punct!(":"),
811 separated_nonempty_list!(punct!("+"), ty_param_bound)
812 )) >>
813 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700814 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700815 (TraitItem {
816 ident: id,
817 attrs: attrs,
818 node: TraitItemKind::Type(bounds, default),
819 })
820 ));
821
822 named!(trait_item_mac -> TraitItem, do_parse!(
823 attrs: many0!(outer_attr) >>
David Tolnay5d55ef72016-12-21 20:20:04 -0500824 what: path >>
David Tolnay0aecb732016-10-03 23:03:50 -0700825 punct!("!") >>
826 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700827 cond!(match body.delim {
828 DelimToken::Paren | DelimToken::Bracket => true,
829 DelimToken::Brace => false,
830 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700831 (TraitItem {
David Tolnay5d55ef72016-12-21 20:20:04 -0500832 ident: Ident::new(""),
David Tolnay0aecb732016-10-03 23:03:50 -0700833 attrs: attrs,
834 node: TraitItemKind::Macro(Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -0500835 path: what,
David Tolnay0aecb732016-10-03 23:03:50 -0700836 tts: vec![TokenTree::Delimited(body)],
837 }),
838 })
839 ));
840
David Tolnay4c9be372016-10-06 00:47:37 -0700841 named!(item_impl -> Item, do_parse!(
842 attrs: many0!(outer_attr) >>
843 unsafety: unsafety >>
844 keyword!("impl") >>
845 generics: generics >>
846 polarity_path: alt!(
847 do_parse!(
848 polarity: impl_polarity >>
849 path: path >>
850 keyword!("for") >>
David Tolnay02a8d472017-02-19 12:59:44 -0800851 (polarity, Some(path))
David Tolnay4c9be372016-10-06 00:47:37 -0700852 )
853 |
854 epsilon!() => { |_| (ImplPolarity::Positive, None) }
855 ) >>
856 self_ty: ty >>
857 where_clause: where_clause >>
858 punct!("{") >>
859 body: many0!(impl_item) >>
860 punct!("}") >>
861 (Item {
862 ident: "".into(),
863 vis: Visibility::Inherited,
864 attrs: attrs,
865 node: ItemKind::Impl(
866 unsafety,
867 polarity_path.0,
868 Generics {
869 where_clause: where_clause,
870 .. generics
871 },
872 polarity_path.1,
873 Box::new(self_ty),
874 body,
875 ),
876 })
877 ));
878
879 named!(impl_item -> ImplItem, alt!(
880 impl_item_const
881 |
882 impl_item_method
883 |
884 impl_item_type
885 |
886 impl_item_macro
887 ));
888
889 named!(impl_item_const -> ImplItem, do_parse!(
890 attrs: many0!(outer_attr) >>
891 vis: visibility >>
892 defaultness: defaultness >>
893 keyword!("const") >>
894 id: ident >>
895 punct!(":") >>
896 ty: ty >>
897 punct!("=") >>
898 value: expr >>
899 punct!(";") >>
900 (ImplItem {
901 ident: id,
902 vis: vis,
903 defaultness: defaultness,
904 attrs: attrs,
905 node: ImplItemKind::Const(ty, value),
906 })
907 ));
908
909 named!(impl_item_method -> ImplItem, do_parse!(
David Tolnay3b9783a2016-10-29 22:37:09 -0700910 outer_attrs: many0!(outer_attr) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700911 vis: visibility >>
912 defaultness: defaultness >>
913 constness: constness >>
914 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700915 abi: option!(abi) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700916 keyword!("fn") >>
917 name: ident >>
918 generics: generics >>
919 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700920 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700921 punct!(")") >>
922 ret: option!(preceded!(punct!("->"), ty)) >>
923 where_clause: where_clause >>
David Tolnay3b9783a2016-10-29 22:37:09 -0700924 punct!("{") >>
925 inner_attrs: many0!(inner_attr) >>
926 stmts: within_block >>
927 punct!("}") >>
David Tolnay4c9be372016-10-06 00:47:37 -0700928 (ImplItem {
929 ident: name,
930 vis: vis,
931 defaultness: defaultness,
David Tolnay3b9783a2016-10-29 22:37:09 -0700932 attrs: {
933 let mut attrs = outer_attrs;
934 attrs.extend(inner_attrs);
935 attrs
936 },
David Tolnay4c9be372016-10-06 00:47:37 -0700937 node: ImplItemKind::Method(
938 MethodSig {
939 unsafety: unsafety,
940 constness: constness,
David Tolnayb8d8ef52016-10-29 14:30:08 -0700941 abi: abi,
David Tolnay4c9be372016-10-06 00:47:37 -0700942 decl: FnDecl {
943 inputs: inputs,
944 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700945 variadic: false,
David Tolnay4c9be372016-10-06 00:47:37 -0700946 },
947 generics: Generics {
948 where_clause: where_clause,
949 .. generics
950 },
951 },
David Tolnay3b9783a2016-10-29 22:37:09 -0700952 Block {
953 stmts: stmts,
954 },
David Tolnay4c9be372016-10-06 00:47:37 -0700955 ),
956 })
957 ));
958
959 named!(impl_item_type -> ImplItem, do_parse!(
960 attrs: many0!(outer_attr) >>
961 vis: visibility >>
962 defaultness: defaultness >>
963 keyword!("type") >>
964 id: ident >>
965 punct!("=") >>
966 ty: ty >>
967 punct!(";") >>
968 (ImplItem {
969 ident: id,
970 vis: vis,
971 defaultness: defaultness,
972 attrs: attrs,
973 node: ImplItemKind::Type(ty),
974 })
975 ));
976
977 named!(impl_item_macro -> ImplItem, do_parse!(
978 attrs: many0!(outer_attr) >>
David Tolnay5d55ef72016-12-21 20:20:04 -0500979 what: path >>
David Tolnay4c9be372016-10-06 00:47:37 -0700980 punct!("!") >>
981 body: delimited >>
982 cond!(match body.delim {
983 DelimToken::Paren | DelimToken::Bracket => true,
984 DelimToken::Brace => false,
985 }, punct!(";")) >>
986 (ImplItem {
David Tolnay5d55ef72016-12-21 20:20:04 -0500987 ident: Ident::new(""),
David Tolnay4c9be372016-10-06 00:47:37 -0700988 vis: Visibility::Inherited,
989 defaultness: Defaultness::Final,
990 attrs: attrs,
991 node: ImplItemKind::Macro(Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -0500992 path: what,
David Tolnay4c9be372016-10-06 00:47:37 -0700993 tts: vec![TokenTree::Delimited(body)],
994 }),
995 })
996 ));
997
998 named!(impl_polarity -> ImplPolarity, alt!(
999 punct!("!") => { |_| ImplPolarity::Negative }
1000 |
1001 epsilon!() => { |_| ImplPolarity::Positive }
1002 ));
1003
David Tolnay42602292016-10-01 22:25:45 -07001004 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -07001005 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -07001006 |
1007 epsilon!() => { |_| Constness::NotConst }
1008 ));
1009
David Tolnay4c9be372016-10-06 00:47:37 -07001010 named!(defaultness -> Defaultness, alt!(
1011 keyword!("default") => { |_| Defaultness::Default }
1012 |
1013 epsilon!() => { |_| Defaultness::Final }
1014 ));
David Tolnayedf2b992016-09-23 20:43:45 -07001015}
David Tolnay4a51dc72016-10-01 00:40:31 -07001016
1017#[cfg(feature = "printing")]
1018mod printing {
1019 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -07001020 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -07001021 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -07001022 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -07001023 use quote::{Tokens, ToTokens};
1024
1025 impl ToTokens for Item {
1026 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001027 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -07001028 match self.node {
1029 ItemKind::ExternCrate(ref original) => {
David Tolnaycbd9f7d2016-10-30 00:26:29 -07001030 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001031 tokens.append("extern");
1032 tokens.append("crate");
1033 if let Some(ref original) = *original {
1034 original.to_tokens(tokens);
1035 tokens.append("as");
1036 }
1037 self.ident.to_tokens(tokens);
1038 tokens.append(";");
1039 }
David Tolnay4a057422016-10-08 00:02:31 -07001040 ItemKind::Use(ref view_path) => {
1041 self.vis.to_tokens(tokens);
1042 tokens.append("use");
1043 view_path.to_tokens(tokens);
1044 tokens.append(";");
1045 }
David Tolnay47a877c2016-10-01 16:50:55 -07001046 ItemKind::Static(ref ty, ref mutability, ref expr) => {
1047 self.vis.to_tokens(tokens);
1048 tokens.append("static");
1049 mutability.to_tokens(tokens);
1050 self.ident.to_tokens(tokens);
1051 tokens.append(":");
1052 ty.to_tokens(tokens);
1053 tokens.append("=");
1054 expr.to_tokens(tokens);
1055 tokens.append(";");
1056 }
1057 ItemKind::Const(ref ty, ref expr) => {
1058 self.vis.to_tokens(tokens);
1059 tokens.append("const");
1060 self.ident.to_tokens(tokens);
1061 tokens.append(":");
1062 ty.to_tokens(tokens);
1063 tokens.append("=");
1064 expr.to_tokens(tokens);
1065 tokens.append(";");
1066 }
David Tolnay42602292016-10-01 22:25:45 -07001067 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
1068 self.vis.to_tokens(tokens);
1069 constness.to_tokens(tokens);
1070 unsafety.to_tokens(tokens);
1071 abi.to_tokens(tokens);
1072 tokens.append("fn");
1073 self.ident.to_tokens(tokens);
1074 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -07001075 tokens.append("(");
1076 tokens.append_separated(&decl.inputs, ",");
1077 tokens.append(")");
1078 if let FunctionRetTy::Ty(ref ty) = decl.output {
1079 tokens.append("->");
1080 ty.to_tokens(tokens);
1081 }
David Tolnay42602292016-10-01 22:25:45 -07001082 generics.where_clause.to_tokens(tokens);
David Tolnay3b9783a2016-10-29 22:37:09 -07001083 tokens.append("{");
1084 tokens.append_all(self.attrs.inner());
1085 tokens.append_all(&block.stmts);
1086 tokens.append("}");
David Tolnay42602292016-10-01 22:25:45 -07001087 }
David Tolnay35902302016-10-06 01:11:08 -07001088 ItemKind::Mod(ref items) => {
1089 self.vis.to_tokens(tokens);
1090 tokens.append("mod");
1091 self.ident.to_tokens(tokens);
David Tolnay37d10332016-10-13 20:51:04 -07001092 match *items {
1093 Some(ref items) => {
1094 tokens.append("{");
David Tolnay7b8009b2016-10-25 22:36:00 -07001095 tokens.append_all(self.attrs.inner());
David Tolnay37d10332016-10-13 20:51:04 -07001096 tokens.append_all(items);
1097 tokens.append("}");
1098 }
1099 None => tokens.append(";"),
1100 }
David Tolnay35902302016-10-06 01:11:08 -07001101 }
1102 ItemKind::ForeignMod(ref foreign_mod) => {
1103 self.vis.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001104 foreign_mod.abi.to_tokens(tokens);
David Tolnay35902302016-10-06 01:11:08 -07001105 tokens.append("{");
1106 tokens.append_all(&foreign_mod.items);
1107 tokens.append("}");
1108 }
David Tolnay3cf52982016-10-01 17:11:37 -07001109 ItemKind::Ty(ref ty, ref generics) => {
1110 self.vis.to_tokens(tokens);
1111 tokens.append("type");
1112 self.ident.to_tokens(tokens);
1113 generics.to_tokens(tokens);
David Tolnay04bb3ad2016-10-30 10:59:01 -07001114 generics.where_clause.to_tokens(tokens);
David Tolnay3cf52982016-10-01 17:11:37 -07001115 tokens.append("=");
1116 ty.to_tokens(tokens);
1117 tokens.append(";");
1118 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001119 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001120 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001121 tokens.append("enum");
1122 self.ident.to_tokens(tokens);
1123 generics.to_tokens(tokens);
1124 generics.where_clause.to_tokens(tokens);
1125 tokens.append("{");
1126 for variant in variants {
1127 variant.to_tokens(tokens);
1128 tokens.append(",");
1129 }
1130 tokens.append("}");
1131 }
1132 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001133 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001134 tokens.append("struct");
1135 self.ident.to_tokens(tokens);
1136 generics.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001137 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -07001138 VariantData::Struct(_) => {
David Tolnay28c1db62016-10-27 22:48:18 -07001139 generics.where_clause.to_tokens(tokens);
1140 variant_data.to_tokens(tokens);
David Tolnaydaaf7742016-10-03 11:11:43 -07001141 // no semicolon
1142 }
David Tolnay28c1db62016-10-27 22:48:18 -07001143 VariantData::Tuple(_) => {
1144 variant_data.to_tokens(tokens);
1145 generics.where_clause.to_tokens(tokens);
1146 tokens.append(";");
1147 }
1148 VariantData::Unit => {
1149 generics.where_clause.to_tokens(tokens);
1150 tokens.append(";");
1151 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001152 }
1153 }
David Tolnay2f9fa632016-10-03 22:08:48 -07001154 ItemKind::Union(ref variant_data, ref generics) => {
1155 self.vis.to_tokens(tokens);
1156 tokens.append("union");
1157 self.ident.to_tokens(tokens);
1158 generics.to_tokens(tokens);
1159 generics.where_clause.to_tokens(tokens);
1160 variant_data.to_tokens(tokens);
1161 }
David Tolnayca085422016-10-04 00:12:38 -07001162 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
1163 self.vis.to_tokens(tokens);
1164 unsafety.to_tokens(tokens);
1165 tokens.append("trait");
1166 self.ident.to_tokens(tokens);
David Tolnaye4606332016-10-25 21:57:41 -07001167 generics.to_tokens(tokens);
David Tolnayca085422016-10-04 00:12:38 -07001168 if !bound.is_empty() {
1169 tokens.append(":");
1170 tokens.append_separated(bound, "+");
1171 }
David Tolnayca085422016-10-04 00:12:38 -07001172 generics.where_clause.to_tokens(tokens);
1173 tokens.append("{");
1174 tokens.append_all(items);
1175 tokens.append("}");
1176 }
David Tolnayf94e2362016-10-04 00:29:51 -07001177 ItemKind::DefaultImpl(unsafety, ref path) => {
1178 unsafety.to_tokens(tokens);
1179 tokens.append("impl");
1180 path.to_tokens(tokens);
1181 tokens.append("for");
1182 tokens.append("..");
1183 tokens.append("{");
1184 tokens.append("}");
1185 }
David Tolnay3bcfb722016-10-08 11:58:36 -07001186 ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => {
David Tolnay4c9be372016-10-06 00:47:37 -07001187 unsafety.to_tokens(tokens);
1188 tokens.append("impl");
1189 generics.to_tokens(tokens);
1190 if let Some(ref path) = *path {
1191 polarity.to_tokens(tokens);
1192 path.to_tokens(tokens);
1193 tokens.append("for");
1194 }
1195 ty.to_tokens(tokens);
1196 generics.where_clause.to_tokens(tokens);
1197 tokens.append("{");
1198 tokens.append_all(items);
1199 tokens.append("}");
1200 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001201 ItemKind::Mac(ref mac) => {
1202 mac.path.to_tokens(tokens);
1203 tokens.append("!");
1204 self.ident.to_tokens(tokens);
1205 for tt in &mac.tts {
1206 tt.to_tokens(tokens);
1207 }
1208 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -07001209 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1210 // no semicolon
1211 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001212 _ => tokens.append(";"),
1213 }
1214 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001215 }
1216 }
1217 }
David Tolnay42602292016-10-01 22:25:45 -07001218
David Tolnay4a057422016-10-08 00:02:31 -07001219 impl ToTokens for ViewPath {
1220 fn to_tokens(&self, tokens: &mut Tokens) {
1221 match *self {
1222 ViewPath::Simple(ref path, ref rename) => {
1223 path.to_tokens(tokens);
1224 if let Some(ref rename) = *rename {
1225 tokens.append("as");
1226 rename.to_tokens(tokens);
1227 }
1228 }
1229 ViewPath::Glob(ref path) => {
1230 path.to_tokens(tokens);
1231 tokens.append("::");
1232 tokens.append("*");
1233 }
1234 ViewPath::List(ref path, ref items) => {
1235 path.to_tokens(tokens);
David Tolnay12417832016-10-08 00:12:37 -07001236 if path.global || !path.segments.is_empty() {
1237 tokens.append("::");
1238 }
David Tolnay4a057422016-10-08 00:02:31 -07001239 tokens.append("{");
1240 tokens.append_separated(items, ",");
1241 tokens.append("}");
1242 }
1243 }
1244 }
1245 }
1246
1247 impl ToTokens for PathListItem {
1248 fn to_tokens(&self, tokens: &mut Tokens) {
1249 self.name.to_tokens(tokens);
1250 if let Some(ref rename) = self.rename {
1251 tokens.append("as");
1252 rename.to_tokens(tokens);
1253 }
1254 }
1255 }
1256
David Tolnayca085422016-10-04 00:12:38 -07001257 impl ToTokens for TraitItem {
1258 fn to_tokens(&self, tokens: &mut Tokens) {
1259 tokens.append_all(self.attrs.outer());
1260 match self.node {
1261 TraitItemKind::Const(ref ty, ref expr) => {
1262 tokens.append("const");
1263 self.ident.to_tokens(tokens);
1264 tokens.append(":");
1265 ty.to_tokens(tokens);
1266 if let Some(ref expr) = *expr {
1267 tokens.append("=");
1268 expr.to_tokens(tokens);
1269 }
1270 tokens.append(";");
1271 }
1272 TraitItemKind::Method(ref sig, ref block) => {
David Tolnayb31d3f02016-10-25 21:15:13 -07001273 sig.constness.to_tokens(tokens);
David Tolnayca085422016-10-04 00:12:38 -07001274 sig.unsafety.to_tokens(tokens);
1275 sig.abi.to_tokens(tokens);
1276 tokens.append("fn");
1277 self.ident.to_tokens(tokens);
1278 sig.generics.to_tokens(tokens);
1279 tokens.append("(");
1280 tokens.append_separated(&sig.decl.inputs, ",");
1281 tokens.append(")");
1282 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1283 tokens.append("->");
1284 ty.to_tokens(tokens);
1285 }
1286 sig.generics.where_clause.to_tokens(tokens);
1287 match *block {
David Tolnay3b9783a2016-10-29 22:37:09 -07001288 Some(ref block) => {
1289 tokens.append("{");
1290 tokens.append_all(self.attrs.inner());
1291 tokens.append_all(&block.stmts);
1292 tokens.append("}");
1293 }
David Tolnayca085422016-10-04 00:12:38 -07001294 None => tokens.append(";"),
1295 }
1296 }
1297 TraitItemKind::Type(ref bound, ref default) => {
1298 tokens.append("type");
1299 self.ident.to_tokens(tokens);
1300 if !bound.is_empty() {
1301 tokens.append(":");
1302 tokens.append_separated(bound, "+");
1303 }
1304 if let Some(ref default) = *default {
1305 tokens.append("=");
1306 default.to_tokens(tokens);
1307 }
1308 tokens.append(";");
1309 }
1310 TraitItemKind::Macro(ref mac) => {
1311 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -07001312 match mac.tts.last() {
1313 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1314 // no semicolon
1315 }
1316 _ => tokens.append(";"),
1317 }
David Tolnayca085422016-10-04 00:12:38 -07001318 }
1319 }
1320 }
1321 }
1322
David Tolnay4c9be372016-10-06 00:47:37 -07001323 impl ToTokens for ImplItem {
1324 fn to_tokens(&self, tokens: &mut Tokens) {
1325 tokens.append_all(self.attrs.outer());
1326 match self.node {
1327 ImplItemKind::Const(ref ty, ref expr) => {
1328 self.vis.to_tokens(tokens);
1329 self.defaultness.to_tokens(tokens);
1330 tokens.append("const");
1331 self.ident.to_tokens(tokens);
1332 tokens.append(":");
1333 ty.to_tokens(tokens);
1334 tokens.append("=");
1335 expr.to_tokens(tokens);
1336 tokens.append(";");
1337 }
1338 ImplItemKind::Method(ref sig, ref block) => {
1339 self.vis.to_tokens(tokens);
1340 self.defaultness.to_tokens(tokens);
David Tolnayb31d3f02016-10-25 21:15:13 -07001341 sig.constness.to_tokens(tokens);
David Tolnay4c9be372016-10-06 00:47:37 -07001342 sig.unsafety.to_tokens(tokens);
1343 sig.abi.to_tokens(tokens);
1344 tokens.append("fn");
1345 self.ident.to_tokens(tokens);
1346 sig.generics.to_tokens(tokens);
1347 tokens.append("(");
1348 tokens.append_separated(&sig.decl.inputs, ",");
1349 tokens.append(")");
1350 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1351 tokens.append("->");
1352 ty.to_tokens(tokens);
1353 }
1354 sig.generics.where_clause.to_tokens(tokens);
David Tolnay5859df12016-10-29 22:49:54 -07001355 tokens.append("{");
1356 tokens.append_all(self.attrs.inner());
1357 tokens.append_all(&block.stmts);
1358 tokens.append("}");
David Tolnay4c9be372016-10-06 00:47:37 -07001359 }
1360 ImplItemKind::Type(ref ty) => {
1361 self.vis.to_tokens(tokens);
1362 self.defaultness.to_tokens(tokens);
1363 tokens.append("type");
1364 self.ident.to_tokens(tokens);
1365 tokens.append("=");
1366 ty.to_tokens(tokens);
1367 tokens.append(";");
1368 }
1369 ImplItemKind::Macro(ref mac) => {
1370 mac.to_tokens(tokens);
1371 match mac.tts.last() {
1372 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1373 // no semicolon
1374 }
1375 _ => tokens.append(";"),
1376 }
1377 }
1378 }
1379 }
1380 }
1381
David Tolnay35902302016-10-06 01:11:08 -07001382 impl ToTokens for ForeignItem {
1383 fn to_tokens(&self, tokens: &mut Tokens) {
1384 tokens.append_all(self.attrs.outer());
1385 match self.node {
1386 ForeignItemKind::Fn(ref decl, ref generics) => {
1387 self.vis.to_tokens(tokens);
1388 tokens.append("fn");
1389 self.ident.to_tokens(tokens);
1390 generics.to_tokens(tokens);
1391 tokens.append("(");
1392 tokens.append_separated(&decl.inputs, ",");
David Tolnay292e6002016-10-29 22:03:51 -07001393 if decl.variadic {
1394 if !decl.inputs.is_empty() {
1395 tokens.append(",");
1396 }
1397 tokens.append("...");
1398 }
David Tolnay35902302016-10-06 01:11:08 -07001399 tokens.append(")");
1400 if let FunctionRetTy::Ty(ref ty) = decl.output {
1401 tokens.append("->");
1402 ty.to_tokens(tokens);
1403 }
1404 generics.where_clause.to_tokens(tokens);
1405 tokens.append(";");
1406 }
1407 ForeignItemKind::Static(ref ty, mutability) => {
1408 self.vis.to_tokens(tokens);
1409 tokens.append("static");
1410 mutability.to_tokens(tokens);
1411 self.ident.to_tokens(tokens);
1412 tokens.append(":");
1413 ty.to_tokens(tokens);
1414 tokens.append(";");
1415 }
1416 }
1417 }
1418 }
1419
David Tolnay62f374c2016-10-02 13:37:00 -07001420 impl ToTokens for FnArg {
1421 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001422 match *self {
1423 FnArg::SelfRef(ref lifetime, mutability) => {
1424 tokens.append("&");
1425 lifetime.to_tokens(tokens);
1426 mutability.to_tokens(tokens);
1427 tokens.append("self");
1428 }
1429 FnArg::SelfValue(mutability) => {
1430 mutability.to_tokens(tokens);
1431 tokens.append("self");
1432 }
1433 FnArg::Captured(ref pat, ref ty) => {
1434 pat.to_tokens(tokens);
1435 tokens.append(":");
1436 ty.to_tokens(tokens);
1437 }
1438 FnArg::Ignored(ref ty) => {
1439 ty.to_tokens(tokens);
1440 }
1441 }
David Tolnay62f374c2016-10-02 13:37:00 -07001442 }
1443 }
1444
David Tolnay42602292016-10-01 22:25:45 -07001445 impl ToTokens for Constness {
1446 fn to_tokens(&self, tokens: &mut Tokens) {
1447 match *self {
1448 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001449 Constness::NotConst => {
1450 // nothing
1451 }
David Tolnay42602292016-10-01 22:25:45 -07001452 }
1453 }
1454 }
1455
David Tolnay4c9be372016-10-06 00:47:37 -07001456 impl ToTokens for Defaultness {
1457 fn to_tokens(&self, tokens: &mut Tokens) {
1458 match *self {
1459 Defaultness::Default => tokens.append("default"),
1460 Defaultness::Final => {
1461 // nothing
1462 }
1463 }
1464 }
1465 }
1466
1467 impl ToTokens for ImplPolarity {
1468 fn to_tokens(&self, tokens: &mut Tokens) {
1469 match *self {
1470 ImplPolarity::Negative => tokens.append("!"),
1471 ImplPolarity::Positive => {
1472 // nothing
1473 }
1474 }
1475 }
1476 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001477}