blob: 7b3eac278864c091e4bf1b7a0b4c48430b52f2e6 [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 Tolnay4c9be372016-10-06 00:47:37 -0700265 |
266 item_impl
David Tolnay84aa0752016-10-02 23:01:13 -0700267 |
268 item_mac
269 ));
270
271 named!(item_mac -> Item, do_parse!(
272 attrs: many0!(outer_attr) >>
273 path: ident >>
274 punct!("!") >>
275 name: option!(ident) >>
276 body: delimited >>
277 (Item {
278 ident: name.unwrap_or_else(|| Ident::new("")),
279 vis: Visibility::Inherited,
280 attrs: attrs,
281 node: ItemKind::Mac(Mac {
282 path: path.into(),
283 tts: vec![TokenTree::Delimited(body)],
284 }),
285 })
David Tolnayedf2b992016-09-23 20:43:45 -0700286 ));
287
David Tolnaya96a3fa2016-09-24 07:17:42 -0700288 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700289 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700290 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700291 keyword!("extern") >>
292 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700293 id: ident >>
294 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700295 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700296 ident
297 )) >>
298 punct!(";") >>
299 ({
300 let (name, original_name) = match rename {
301 Some(rename) => (rename, Some(id)),
302 None => (id, None),
303 };
304 Item {
305 ident: name,
306 vis: vis,
307 attrs: attrs,
308 node: ItemKind::ExternCrate(original_name),
309 }
310 })
311 ));
312
David Tolnay47a877c2016-10-01 16:50:55 -0700313 named!(item_static -> Item, do_parse!(
314 attrs: many0!(outer_attr) >>
315 vis: visibility >>
316 keyword!("static") >>
317 mutability: mutability >>
318 id: ident >>
319 punct!(":") >>
320 ty: ty >>
321 punct!("=") >>
322 value: expr >>
323 punct!(";") >>
324 (Item {
325 ident: id,
326 vis: vis,
327 attrs: attrs,
328 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
329 })
330 ));
331
332 named!(item_const -> Item, do_parse!(
333 attrs: many0!(outer_attr) >>
334 vis: visibility >>
335 keyword!("const") >>
336 id: ident >>
337 punct!(":") >>
338 ty: ty >>
339 punct!("=") >>
340 value: expr >>
341 punct!(";") >>
342 (Item {
343 ident: id,
344 vis: vis,
345 attrs: attrs,
346 node: ItemKind::Const(Box::new(ty), Box::new(value)),
347 })
348 ));
349
David Tolnay42602292016-10-01 22:25:45 -0700350 named!(item_fn -> Item, do_parse!(
351 attrs: many0!(outer_attr) >>
352 vis: visibility >>
353 constness: constness >>
354 unsafety: unsafety >>
355 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
356 keyword!("fn") >>
357 name: ident >>
358 generics: generics >>
359 punct!("(") >>
360 inputs: separated_list!(punct!(","), fn_arg) >>
361 punct!(")") >>
362 ret: option!(preceded!(punct!("->"), ty)) >>
363 where_clause: where_clause >>
364 body: block >>
365 (Item {
366 ident: name,
367 vis: vis,
368 attrs: attrs,
369 node: ItemKind::Fn(
370 Box::new(FnDecl {
371 inputs: inputs,
372 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
373 }),
374 unsafety,
375 constness,
376 abi.map(Abi),
377 Generics {
378 where_clause: where_clause,
379 .. generics
380 },
381 Box::new(body),
382 ),
383 })
384 ));
385
David Tolnayca085422016-10-04 00:12:38 -0700386 named!(fn_arg -> FnArg, alt!(
387 do_parse!(
388 punct!("&") >>
389 lt: option!(lifetime) >>
390 mutability: mutability >>
391 keyword!("self") >>
392 (FnArg::SelfRef(lt, mutability))
393 )
394 |
395 do_parse!(
396 mutability: mutability >>
397 keyword!("self") >>
398 (FnArg::SelfValue(mutability))
399 )
400 |
401 do_parse!(
402 pat: pat >>
403 punct!(":") >>
404 ty: ty >>
405 (FnArg::Captured(pat, ty))
406 )
407 |
408 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700409 ));
410
David Tolnay3cf52982016-10-01 17:11:37 -0700411 named!(item_ty -> Item, do_parse!(
412 attrs: many0!(outer_attr) >>
413 vis: visibility >>
414 keyword!("type") >>
415 id: ident >>
416 generics: generics >>
417 punct!("=") >>
418 ty: ty >>
419 punct!(";") >>
420 (Item {
421 ident: id,
422 vis: vis,
423 attrs: attrs,
424 node: ItemKind::Ty(Box::new(ty), generics),
425 })
426 ));
427
David Tolnaya96a3fa2016-09-24 07:17:42 -0700428 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700429 macro_input,
430 |def: MacroInput| Item {
431 ident: def.ident,
432 vis: def.vis,
433 attrs: def.attrs,
434 node: match def.body {
435 Body::Enum(variants) => {
436 ItemKind::Enum(variants, def.generics)
437 }
438 Body::Struct(variant_data) => {
439 ItemKind::Struct(variant_data, def.generics)
440 }
441 }
442 }
443 ));
David Tolnay42602292016-10-01 22:25:45 -0700444
David Tolnay2f9fa632016-10-03 22:08:48 -0700445 named!(item_union -> Item, do_parse!(
446 attrs: many0!(outer_attr) >>
447 vis: visibility >>
448 keyword!("union") >>
449 id: ident >>
450 generics: generics >>
451 where_clause: where_clause >>
452 fields: struct_like_body >>
453 (Item {
454 ident: id,
455 vis: vis,
456 attrs: attrs,
457 node: ItemKind::Union(
458 VariantData::Struct(fields),
459 Generics {
460 where_clause: where_clause,
461 .. generics
462 },
463 ),
464 })
465 ));
466
David Tolnay0aecb732016-10-03 23:03:50 -0700467 named!(item_trait -> Item, do_parse!(
468 attrs: many0!(outer_attr) >>
469 vis: visibility >>
470 unsafety: unsafety >>
471 keyword!("trait") >>
472 id: ident >>
473 generics: generics >>
474 bounds: opt_vec!(preceded!(
475 punct!(":"),
476 separated_nonempty_list!(punct!("+"), ty_param_bound)
477 )) >>
478 where_clause: where_clause >>
479 punct!("{") >>
480 body: many0!(trait_item) >>
481 punct!("}") >>
482 (Item {
483 ident: id,
484 vis: vis,
485 attrs: attrs,
486 node: ItemKind::Trait(
487 unsafety,
488 Generics {
489 where_clause: where_clause,
490 .. generics
491 },
492 bounds,
493 body,
494 ),
495 })
496 ));
497
David Tolnayf94e2362016-10-04 00:29:51 -0700498 named!(item_default_impl -> Item, do_parse!(
499 attrs: many0!(outer_attr) >>
500 unsafety: unsafety >>
501 keyword!("impl") >>
502 path: path >>
503 keyword!("for") >>
504 punct!("..") >>
505 punct!("{") >>
506 punct!("}") >>
507 (Item {
508 ident: "".into(),
509 vis: Visibility::Inherited,
510 attrs: attrs,
511 node: ItemKind::DefaultImpl(unsafety, path),
512 })
513 ));
514
David Tolnay0aecb732016-10-03 23:03:50 -0700515 named!(trait_item -> TraitItem, alt!(
516 trait_item_const
517 |
518 trait_item_method
519 |
520 trait_item_type
521 |
522 trait_item_mac
523 ));
524
525 named!(trait_item_const -> TraitItem, do_parse!(
526 attrs: many0!(outer_attr) >>
527 keyword!("const") >>
528 id: ident >>
529 punct!(":") >>
530 ty: ty >>
531 value: option!(preceded!(punct!("="), expr)) >>
532 punct!(";") >>
533 (TraitItem {
534 ident: id,
535 attrs: attrs,
536 node: TraitItemKind::Const(ty, value),
537 })
538 ));
539
540 named!(trait_item_method -> TraitItem, do_parse!(
541 attrs: many0!(outer_attr) >>
542 constness: constness >>
543 unsafety: unsafety >>
544 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
545 keyword!("fn") >>
546 name: ident >>
547 generics: generics >>
548 punct!("(") >>
549 inputs: separated_list!(punct!(","), fn_arg) >>
550 punct!(")") >>
551 ret: option!(preceded!(punct!("->"), ty)) >>
552 where_clause: where_clause >>
553 body: option!(block) >>
554 cond!(body.is_none(), punct!(";")) >>
555 (TraitItem {
556 ident: name,
557 attrs: attrs,
558 node: TraitItemKind::Method(
559 MethodSig {
560 unsafety: unsafety,
561 constness: constness,
562 abi: abi.map(Abi),
563 decl: FnDecl {
564 inputs: inputs,
565 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
566 },
567 generics: Generics {
568 where_clause: where_clause,
569 .. generics
570 },
571 },
572 body,
573 ),
574 })
575 ));
576
577 named!(trait_item_type -> TraitItem, do_parse!(
578 attrs: many0!(outer_attr) >>
579 keyword!("type") >>
580 id: ident >>
581 bounds: opt_vec!(preceded!(
582 punct!(":"),
583 separated_nonempty_list!(punct!("+"), ty_param_bound)
584 )) >>
585 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700586 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700587 (TraitItem {
588 ident: id,
589 attrs: attrs,
590 node: TraitItemKind::Type(bounds, default),
591 })
592 ));
593
594 named!(trait_item_mac -> TraitItem, do_parse!(
595 attrs: many0!(outer_attr) >>
596 id: ident >>
597 punct!("!") >>
598 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700599 cond!(match body.delim {
600 DelimToken::Paren | DelimToken::Bracket => true,
601 DelimToken::Brace => false,
602 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700603 (TraitItem {
604 ident: id.clone(),
605 attrs: attrs,
606 node: TraitItemKind::Macro(Mac {
607 path: id.into(),
608 tts: vec![TokenTree::Delimited(body)],
609 }),
610 })
611 ));
612
David Tolnay4c9be372016-10-06 00:47:37 -0700613 named!(item_impl -> Item, do_parse!(
614 attrs: many0!(outer_attr) >>
615 unsafety: unsafety >>
616 keyword!("impl") >>
617 generics: generics >>
618 polarity_path: alt!(
619 do_parse!(
620 polarity: impl_polarity >>
621 path: path >>
622 keyword!("for") >>
623 ((polarity, Some(path)))
624 )
625 |
626 epsilon!() => { |_| (ImplPolarity::Positive, None) }
627 ) >>
628 self_ty: ty >>
629 where_clause: where_clause >>
630 punct!("{") >>
631 body: many0!(impl_item) >>
632 punct!("}") >>
633 (Item {
634 ident: "".into(),
635 vis: Visibility::Inherited,
636 attrs: attrs,
637 node: ItemKind::Impl(
638 unsafety,
639 polarity_path.0,
640 Generics {
641 where_clause: where_clause,
642 .. generics
643 },
644 polarity_path.1,
645 Box::new(self_ty),
646 body,
647 ),
648 })
649 ));
650
651 named!(impl_item -> ImplItem, alt!(
652 impl_item_const
653 |
654 impl_item_method
655 |
656 impl_item_type
657 |
658 impl_item_macro
659 ));
660
661 named!(impl_item_const -> ImplItem, do_parse!(
662 attrs: many0!(outer_attr) >>
663 vis: visibility >>
664 defaultness: defaultness >>
665 keyword!("const") >>
666 id: ident >>
667 punct!(":") >>
668 ty: ty >>
669 punct!("=") >>
670 value: expr >>
671 punct!(";") >>
672 (ImplItem {
673 ident: id,
674 vis: vis,
675 defaultness: defaultness,
676 attrs: attrs,
677 node: ImplItemKind::Const(ty, value),
678 })
679 ));
680
681 named!(impl_item_method -> ImplItem, do_parse!(
682 attrs: many0!(outer_attr) >>
683 vis: visibility >>
684 defaultness: defaultness >>
685 constness: constness >>
686 unsafety: unsafety >>
687 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
688 keyword!("fn") >>
689 name: ident >>
690 generics: generics >>
691 punct!("(") >>
692 inputs: separated_list!(punct!(","), fn_arg) >>
693 punct!(")") >>
694 ret: option!(preceded!(punct!("->"), ty)) >>
695 where_clause: where_clause >>
696 body: block >>
697 (ImplItem {
698 ident: name,
699 vis: vis,
700 defaultness: defaultness,
701 attrs: attrs,
702 node: ImplItemKind::Method(
703 MethodSig {
704 unsafety: unsafety,
705 constness: constness,
706 abi: abi.map(Abi),
707 decl: FnDecl {
708 inputs: inputs,
709 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
710 },
711 generics: Generics {
712 where_clause: where_clause,
713 .. generics
714 },
715 },
716 body,
717 ),
718 })
719 ));
720
721 named!(impl_item_type -> ImplItem, do_parse!(
722 attrs: many0!(outer_attr) >>
723 vis: visibility >>
724 defaultness: defaultness >>
725 keyword!("type") >>
726 id: ident >>
727 punct!("=") >>
728 ty: ty >>
729 punct!(";") >>
730 (ImplItem {
731 ident: id,
732 vis: vis,
733 defaultness: defaultness,
734 attrs: attrs,
735 node: ImplItemKind::Type(ty),
736 })
737 ));
738
739 named!(impl_item_macro -> ImplItem, do_parse!(
740 attrs: many0!(outer_attr) >>
741 id: ident >>
742 punct!("!") >>
743 body: delimited >>
744 cond!(match body.delim {
745 DelimToken::Paren | DelimToken::Bracket => true,
746 DelimToken::Brace => false,
747 }, punct!(";")) >>
748 (ImplItem {
749 ident: id.clone(),
750 vis: Visibility::Inherited,
751 defaultness: Defaultness::Final,
752 attrs: attrs,
753 node: ImplItemKind::Macro(Mac {
754 path: id.into(),
755 tts: vec![TokenTree::Delimited(body)],
756 }),
757 })
758 ));
759
760 named!(impl_polarity -> ImplPolarity, alt!(
761 punct!("!") => { |_| ImplPolarity::Negative }
762 |
763 epsilon!() => { |_| ImplPolarity::Positive }
764 ));
765
David Tolnay42602292016-10-01 22:25:45 -0700766 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700767 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -0700768 |
769 epsilon!() => { |_| Constness::NotConst }
770 ));
771
772 named!(unsafety -> Unsafety, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700773 keyword!("unsafe") => { |_| Unsafety::Unsafe }
David Tolnay42602292016-10-01 22:25:45 -0700774 |
775 epsilon!() => { |_| Unsafety::Normal }
776 ));
David Tolnay4c9be372016-10-06 00:47:37 -0700777
778 named!(defaultness -> Defaultness, alt!(
779 keyword!("default") => { |_| Defaultness::Default }
780 |
781 epsilon!() => { |_| Defaultness::Final }
782 ));
David Tolnayedf2b992016-09-23 20:43:45 -0700783}
David Tolnay4a51dc72016-10-01 00:40:31 -0700784
785#[cfg(feature = "printing")]
786mod printing {
787 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -0700788 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -0700789 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -0700790 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -0700791 use quote::{Tokens, ToTokens};
792
793 impl ToTokens for Item {
794 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700795 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -0700796 match self.node {
797 ItemKind::ExternCrate(ref original) => {
798 tokens.append("extern");
799 tokens.append("crate");
800 if let Some(ref original) = *original {
801 original.to_tokens(tokens);
802 tokens.append("as");
803 }
804 self.ident.to_tokens(tokens);
805 tokens.append(";");
806 }
807 ItemKind::Use(ref _view_path) => unimplemented!(),
David Tolnay47a877c2016-10-01 16:50:55 -0700808 ItemKind::Static(ref ty, ref mutability, ref expr) => {
809 self.vis.to_tokens(tokens);
810 tokens.append("static");
811 mutability.to_tokens(tokens);
812 self.ident.to_tokens(tokens);
813 tokens.append(":");
814 ty.to_tokens(tokens);
815 tokens.append("=");
816 expr.to_tokens(tokens);
817 tokens.append(";");
818 }
819 ItemKind::Const(ref ty, ref expr) => {
820 self.vis.to_tokens(tokens);
821 tokens.append("const");
822 self.ident.to_tokens(tokens);
823 tokens.append(":");
824 ty.to_tokens(tokens);
825 tokens.append("=");
826 expr.to_tokens(tokens);
827 tokens.append(";");
828 }
David Tolnay42602292016-10-01 22:25:45 -0700829 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
830 self.vis.to_tokens(tokens);
831 constness.to_tokens(tokens);
832 unsafety.to_tokens(tokens);
833 abi.to_tokens(tokens);
834 tokens.append("fn");
835 self.ident.to_tokens(tokens);
836 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -0700837 tokens.append("(");
838 tokens.append_separated(&decl.inputs, ",");
839 tokens.append(")");
840 if let FunctionRetTy::Ty(ref ty) = decl.output {
841 tokens.append("->");
842 ty.to_tokens(tokens);
843 }
David Tolnay42602292016-10-01 22:25:45 -0700844 generics.where_clause.to_tokens(tokens);
845 block.to_tokens(tokens);
846 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700847 ItemKind::Mod(ref _items) => unimplemented!(),
848 ItemKind::ForeignMod(ref _foreign_mod) => unimplemented!(),
David Tolnay3cf52982016-10-01 17:11:37 -0700849 ItemKind::Ty(ref ty, ref generics) => {
850 self.vis.to_tokens(tokens);
851 tokens.append("type");
852 self.ident.to_tokens(tokens);
853 generics.to_tokens(tokens);
854 tokens.append("=");
855 ty.to_tokens(tokens);
856 tokens.append(";");
857 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700858 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700859 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700860 tokens.append("enum");
861 self.ident.to_tokens(tokens);
862 generics.to_tokens(tokens);
863 generics.where_clause.to_tokens(tokens);
864 tokens.append("{");
865 for variant in variants {
866 variant.to_tokens(tokens);
867 tokens.append(",");
868 }
869 tokens.append("}");
870 }
871 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700872 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700873 tokens.append("struct");
874 self.ident.to_tokens(tokens);
875 generics.to_tokens(tokens);
876 generics.where_clause.to_tokens(tokens);
877 variant_data.to_tokens(tokens);
878 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -0700879 VariantData::Struct(_) => {
880 // no semicolon
881 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700882 VariantData::Tuple(_) |
883 VariantData::Unit => tokens.append(";"),
884 }
885 }
David Tolnay2f9fa632016-10-03 22:08:48 -0700886 ItemKind::Union(ref variant_data, ref generics) => {
887 self.vis.to_tokens(tokens);
888 tokens.append("union");
889 self.ident.to_tokens(tokens);
890 generics.to_tokens(tokens);
891 generics.where_clause.to_tokens(tokens);
892 variant_data.to_tokens(tokens);
893 }
David Tolnayca085422016-10-04 00:12:38 -0700894 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
895 self.vis.to_tokens(tokens);
896 unsafety.to_tokens(tokens);
897 tokens.append("trait");
898 self.ident.to_tokens(tokens);
899 if !bound.is_empty() {
900 tokens.append(":");
901 tokens.append_separated(bound, "+");
902 }
903 generics.to_tokens(tokens);
904 generics.where_clause.to_tokens(tokens);
905 tokens.append("{");
906 tokens.append_all(items);
907 tokens.append("}");
908 }
David Tolnayf94e2362016-10-04 00:29:51 -0700909 ItemKind::DefaultImpl(unsafety, ref path) => {
910 unsafety.to_tokens(tokens);
911 tokens.append("impl");
912 path.to_tokens(tokens);
913 tokens.append("for");
914 tokens.append("..");
915 tokens.append("{");
916 tokens.append("}");
917 }
David Tolnay4c9be372016-10-06 00:47:37 -0700918 ItemKind::Impl(unsafety,
919 polarity,
920 ref generics,
921 ref path,
922 ref ty,
923 ref items) => {
924 unsafety.to_tokens(tokens);
925 tokens.append("impl");
926 generics.to_tokens(tokens);
927 if let Some(ref path) = *path {
928 polarity.to_tokens(tokens);
929 path.to_tokens(tokens);
930 tokens.append("for");
931 }
932 ty.to_tokens(tokens);
933 generics.where_clause.to_tokens(tokens);
934 tokens.append("{");
935 tokens.append_all(items);
936 tokens.append("}");
937 }
David Tolnaycc3d66e2016-10-02 23:36:05 -0700938 ItemKind::Mac(ref mac) => {
939 mac.path.to_tokens(tokens);
940 tokens.append("!");
941 self.ident.to_tokens(tokens);
942 for tt in &mac.tts {
943 tt.to_tokens(tokens);
944 }
945 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -0700946 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
947 // no semicolon
948 }
David Tolnaycc3d66e2016-10-02 23:36:05 -0700949 _ => tokens.append(";"),
950 }
951 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700952 }
953 }
954 }
David Tolnay42602292016-10-01 22:25:45 -0700955
David Tolnayca085422016-10-04 00:12:38 -0700956 impl ToTokens for TraitItem {
957 fn to_tokens(&self, tokens: &mut Tokens) {
958 tokens.append_all(self.attrs.outer());
959 match self.node {
960 TraitItemKind::Const(ref ty, ref expr) => {
961 tokens.append("const");
962 self.ident.to_tokens(tokens);
963 tokens.append(":");
964 ty.to_tokens(tokens);
965 if let Some(ref expr) = *expr {
966 tokens.append("=");
967 expr.to_tokens(tokens);
968 }
969 tokens.append(";");
970 }
971 TraitItemKind::Method(ref sig, ref block) => {
972 sig.unsafety.to_tokens(tokens);
973 sig.abi.to_tokens(tokens);
974 tokens.append("fn");
975 self.ident.to_tokens(tokens);
976 sig.generics.to_tokens(tokens);
977 tokens.append("(");
978 tokens.append_separated(&sig.decl.inputs, ",");
979 tokens.append(")");
980 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
981 tokens.append("->");
982 ty.to_tokens(tokens);
983 }
984 sig.generics.where_clause.to_tokens(tokens);
985 match *block {
986 Some(ref block) => block.to_tokens(tokens),
987 None => tokens.append(";"),
988 }
989 }
990 TraitItemKind::Type(ref bound, ref default) => {
991 tokens.append("type");
992 self.ident.to_tokens(tokens);
993 if !bound.is_empty() {
994 tokens.append(":");
995 tokens.append_separated(bound, "+");
996 }
997 if let Some(ref default) = *default {
998 tokens.append("=");
999 default.to_tokens(tokens);
1000 }
1001 tokens.append(";");
1002 }
1003 TraitItemKind::Macro(ref mac) => {
1004 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -07001005 match mac.tts.last() {
1006 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1007 // no semicolon
1008 }
1009 _ => tokens.append(";"),
1010 }
David Tolnayca085422016-10-04 00:12:38 -07001011 }
1012 }
1013 }
1014 }
1015
David Tolnay4c9be372016-10-06 00:47:37 -07001016 impl ToTokens for ImplItem {
1017 fn to_tokens(&self, tokens: &mut Tokens) {
1018 tokens.append_all(self.attrs.outer());
1019 match self.node {
1020 ImplItemKind::Const(ref ty, ref expr) => {
1021 self.vis.to_tokens(tokens);
1022 self.defaultness.to_tokens(tokens);
1023 tokens.append("const");
1024 self.ident.to_tokens(tokens);
1025 tokens.append(":");
1026 ty.to_tokens(tokens);
1027 tokens.append("=");
1028 expr.to_tokens(tokens);
1029 tokens.append(";");
1030 }
1031 ImplItemKind::Method(ref sig, ref block) => {
1032 self.vis.to_tokens(tokens);
1033 self.defaultness.to_tokens(tokens);
1034 sig.unsafety.to_tokens(tokens);
1035 sig.abi.to_tokens(tokens);
1036 tokens.append("fn");
1037 self.ident.to_tokens(tokens);
1038 sig.generics.to_tokens(tokens);
1039 tokens.append("(");
1040 tokens.append_separated(&sig.decl.inputs, ",");
1041 tokens.append(")");
1042 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1043 tokens.append("->");
1044 ty.to_tokens(tokens);
1045 }
1046 sig.generics.where_clause.to_tokens(tokens);
1047 block.to_tokens(tokens);
1048 }
1049 ImplItemKind::Type(ref ty) => {
1050 self.vis.to_tokens(tokens);
1051 self.defaultness.to_tokens(tokens);
1052 tokens.append("type");
1053 self.ident.to_tokens(tokens);
1054 tokens.append("=");
1055 ty.to_tokens(tokens);
1056 tokens.append(";");
1057 }
1058 ImplItemKind::Macro(ref mac) => {
1059 mac.to_tokens(tokens);
1060 match mac.tts.last() {
1061 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1062 // no semicolon
1063 }
1064 _ => tokens.append(";"),
1065 }
1066 }
1067 }
1068 }
1069 }
1070
David Tolnay62f374c2016-10-02 13:37:00 -07001071 impl ToTokens for FnArg {
1072 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001073 match *self {
1074 FnArg::SelfRef(ref lifetime, mutability) => {
1075 tokens.append("&");
1076 lifetime.to_tokens(tokens);
1077 mutability.to_tokens(tokens);
1078 tokens.append("self");
1079 }
1080 FnArg::SelfValue(mutability) => {
1081 mutability.to_tokens(tokens);
1082 tokens.append("self");
1083 }
1084 FnArg::Captured(ref pat, ref ty) => {
1085 pat.to_tokens(tokens);
1086 tokens.append(":");
1087 ty.to_tokens(tokens);
1088 }
1089 FnArg::Ignored(ref ty) => {
1090 ty.to_tokens(tokens);
1091 }
1092 }
David Tolnay62f374c2016-10-02 13:37:00 -07001093 }
1094 }
1095
David Tolnay42602292016-10-01 22:25:45 -07001096 impl ToTokens for Unsafety {
1097 fn to_tokens(&self, tokens: &mut Tokens) {
1098 match *self {
1099 Unsafety::Unsafe => tokens.append("unsafe"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001100 Unsafety::Normal => {
1101 // nothing
1102 }
David Tolnay42602292016-10-01 22:25:45 -07001103 }
1104 }
1105 }
1106
1107 impl ToTokens for Constness {
1108 fn to_tokens(&self, tokens: &mut Tokens) {
1109 match *self {
1110 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001111 Constness::NotConst => {
1112 // nothing
1113 }
David Tolnay42602292016-10-01 22:25:45 -07001114 }
1115 }
1116 }
1117
David Tolnay4c9be372016-10-06 00:47:37 -07001118 impl ToTokens for Defaultness {
1119 fn to_tokens(&self, tokens: &mut Tokens) {
1120 match *self {
1121 Defaultness::Default => tokens.append("default"),
1122 Defaultness::Final => {
1123 // nothing
1124 }
1125 }
1126 }
1127 }
1128
1129 impl ToTokens for ImplPolarity {
1130 fn to_tokens(&self, tokens: &mut Tokens) {
1131 match *self {
1132 ImplPolarity::Negative => tokens.append("!"),
1133 ImplPolarity::Positive => {
1134 // nothing
1135 }
1136 }
1137 }
1138 }
1139
David Tolnay42602292016-10-01 22:25:45 -07001140 impl ToTokens for Abi {
1141 fn to_tokens(&self, tokens: &mut Tokens) {
1142 tokens.append("extern");
1143 self.0.to_tokens(tokens);
1144 }
1145 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001146}