blob: a9219febddeeb429c16f4a54650e7812da8e790a [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
David Tolnayf4bbbd92016-09-23 14:41:55 -07009use super::*;
David Tolnayab919512017-12-30 23:31:51 -050010use proc_macro2::TokenStream;
David Tolnay61037c62018-01-05 16:21:03 -080011use token::{Brace, Bracket, Paren};
David Tolnay9c76bcb2017-12-26 23:14:59 -050012
13#[cfg(feature = "extra-traits")]
14use std::hash::{Hash, Hasher};
David Tolnayc43b44e2017-12-30 23:55:54 -050015#[cfg(feature = "extra-traits")]
16use tt::TokenStreamHelper;
Alex Crichtonccbb45d2017-05-23 10:58:24 -070017
Alex Crichton62a0a592017-05-22 13:58:53 -070018ast_struct! {
David Tolnay05658502018-01-07 09:56:37 -080019 /// A macro invocation: `println!("{}", mac)`.
David Tolnay461d98e2018-01-07 11:07:19 -080020 ///
21 /// *This type is available if Syn is built with the `"derive"` or `"full"`
22 /// feature.*
David Tolnay9c76bcb2017-12-26 23:14:59 -050023 pub struct Macro #manual_extra_traits {
Alex Crichton62a0a592017-05-22 13:58:53 -070024 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -080025 pub bang_token: Token![!],
David Tolnayab919512017-12-30 23:31:51 -050026 pub delimiter: MacroDelimiter,
27 pub tts: TokenStream,
28 }
29}
30
31ast_enum! {
David Tolnay05658502018-01-07 09:56:37 -080032 /// A grouping token that surrounds a macro body: `m!(...)` or `m!{...}` or `m![...]`.
David Tolnay461d98e2018-01-07 11:07:19 -080033 ///
34 /// *This type is available if Syn is built with the `"derive"` or `"full"`
35 /// feature.*
David Tolnayab919512017-12-30 23:31:51 -050036 pub enum MacroDelimiter {
David Tolnayab919512017-12-30 23:31:51 -050037 Paren(Paren),
David Tolnayab919512017-12-30 23:31:51 -050038 Brace(Brace),
David Tolnayab919512017-12-30 23:31:51 -050039 Bracket(Bracket),
Alex Crichton62a0a592017-05-22 13:58:53 -070040 }
David Tolnayf4bbbd92016-09-23 14:41:55 -070041}
42
David Tolnay9c76bcb2017-12-26 23:14:59 -050043#[cfg(feature = "extra-traits")]
44impl Eq for Macro {}
45
46#[cfg(feature = "extra-traits")]
47impl PartialEq for Macro {
48 fn eq(&self, other: &Self) -> bool {
David Tolnay65fb5662018-05-20 20:02:28 -070049 self.path == other.path
50 && self.bang_token == other.bang_token
David Tolnayab919512017-12-30 23:31:51 -050051 && self.delimiter == other.delimiter
52 && TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
David Tolnay9c76bcb2017-12-26 23:14:59 -050053 }
54}
55
56#[cfg(feature = "extra-traits")]
57impl Hash for Macro {
58 fn hash<H>(&self, state: &mut H)
David Tolnay51382052017-12-27 13:46:21 -050059 where
60 H: Hasher,
David Tolnay9c76bcb2017-12-26 23:14:59 -050061 {
62 self.path.hash(state);
63 self.bang_token.hash(state);
David Tolnayab919512017-12-30 23:31:51 -050064 self.delimiter.hash(state);
65 TokenStreamHelper(&self.tts).hash(state);
David Tolnay9c76bcb2017-12-26 23:14:59 -050066 }
67}
Alex Crichtonccbb45d2017-05-23 10:58:24 -070068
David Tolnay84aa0752016-10-02 23:01:13 -070069#[cfg(feature = "parsing")]
70pub mod parsing {
71 use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -070072
David Tolnayc5ab8c62017-12-26 16:43:39 -050073 use synom::Synom;
David Tolnay84aa0752016-10-02 23:01:13 -070074
David Tolnaydecf28d2017-11-11 11:56:45 -080075 impl Synom for Macro {
Michael Layzell92639a52017-06-01 00:07:44 -040076 named!(parse -> Self, do_parse!(
David Tolnayd69fc2b2018-01-23 09:39:14 -080077 what: call!(Path::parse_mod_style) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -080078 bang: punct!(!) >>
David Tolnaye0824032017-12-27 15:25:56 -050079 body: call!(tt::delimited) >>
David Tolnaydecf28d2017-11-11 11:56:45 -080080 (Macro {
Michael Layzell92639a52017-06-01 00:07:44 -040081 path: what,
82 bang_token: bang,
David Tolnayab919512017-12-30 23:31:51 -050083 delimiter: body.0,
84 tts: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -040085 })
86 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -080087
88 fn description() -> Option<&'static str> {
89 Some("macro invocation")
90 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070091 }
David Tolnayf4bbbd92016-09-23 14:41:55 -070092}
David Tolnayf8cf9632016-10-02 23:15:25 -070093
94#[cfg(feature = "printing")]
95mod printing {
96 use super::*;
Alex Crichtona74a1c82018-05-16 10:20:44 -070097 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -070098 use quote::ToTokens;
David Tolnayf8cf9632016-10-02 23:15:25 -070099
David Tolnaydecf28d2017-11-11 11:56:45 -0800100 impl ToTokens for Macro {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700101 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnayf8cf9632016-10-02 23:15:25 -0700102 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700103 self.bang_token.to_tokens(tokens);
David Tolnayab919512017-12-30 23:31:51 -0500104 match self.delimiter {
105 MacroDelimiter::Paren(ref paren) => {
106 paren.surround(tokens, |tokens| self.tts.to_tokens(tokens));
107 }
108 MacroDelimiter::Brace(ref brace) => {
109 brace.surround(tokens, |tokens| self.tts.to_tokens(tokens));
110 }
111 MacroDelimiter::Bracket(ref bracket) => {
112 bracket.surround(tokens, |tokens| self.tts.to_tokens(tokens));
113 }
114 }
David Tolnayf8cf9632016-10-02 23:15:25 -0700115 }
116 }
David Tolnayf8cf9632016-10-02 23:15:25 -0700117}