blob: 744cb97c09f405ebd031fc08ba3fc3e7298549ae [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use Span;
2
3macro_rules! tokens {
4 (
5 ops: {
6 $(($($op:tt)*),)*
7 }
8 delim: {
9 $(($($delim:tt)*),)*
10 }
11 syms: {
12 $(($($sym:tt)*),)*
13 }
14 ) => (
15 $(op! { $($op)* })*
16 $(delim! { $($delim)* })*
17 $(sym! { $($sym)* })*
18 )
19}
20
21macro_rules! op {
22 (pub struct $name:ident($($contents:tt)*) => $s:expr) => {
23 ast_struct! {
24 #[cfg_attr(feature = "clone-impls", derive(Copy))]
25 #[derive(Default)]
26 pub struct $name(pub $($contents)*);
27 }
28
29 #[cfg(feature = "printing")]
30 impl ::quote::ToTokens for $name {
31 fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
32 printing::op($s, &self.0, tokens);
33 }
34 }
35 }
36}
37
38macro_rules! sym {
39 (pub struct $name:ident => $s:expr) => {
40 ast_struct! {
41 #[cfg_attr(feature = "clone-impls", derive(Copy))]
42 #[derive(Default)]
43 pub struct $name(pub Span);
44 }
45
46 #[cfg(feature = "printing")]
47 impl ::quote::ToTokens for $name {
48 fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
49 printing::sym($s, &self.0, tokens);
50 }
51 }
52 }
53}
54
55macro_rules! delim {
56 (pub struct $name:ident => $s:expr) => {
57 ast_struct! {
58 #[cfg_attr(feature = "clone-impls", derive(Copy))]
59 #[derive(Default)]
60 pub struct $name(pub Span);
61 }
62
63 #[cfg(feature = "printing")]
64 impl $name {
65 pub fn surround<F>(&self,
66 tokens: &mut ::quote::Tokens,
67 f: F)
68 where F: FnOnce(&mut ::quote::Tokens)
69 {
70 printing::delim($s, &self.0, tokens, f);
71 }
72 }
73 }
74}
75
76tokens! {
77 ops: {
78 (pub struct Add([Span; 1]) => "+"),
79 (pub struct AddEq([Span; 2]) => "+="),
80 (pub struct And([Span; 1]) => "&"),
81 (pub struct AndAnd([Span; 2]) => "&&"),
82 (pub struct AndEq([Span; 2]) => "&="),
83 (pub struct At([Span; 1]) => "@"),
84 (pub struct Bang([Span; 1]) => "!"),
85 (pub struct Caret([Span; 1]) => "^"),
86 (pub struct CaretEq([Span; 2]) => "^="),
87 (pub struct Colon([Span; 1]) => ":"),
88 (pub struct Colon2([Span; 2]) => "::"),
89 (pub struct Comma([Span; 1]) => ","),
90 (pub struct Div([Span; 1]) => "/"),
91 (pub struct DivEq([Span; 2]) => "/="),
92 (pub struct Dot([Span; 1]) => "."),
93 (pub struct Dot2([Span; 2]) => ".."),
94 (pub struct Dot3([Span; 3]) => "..."),
95 (pub struct Eq([Span; 1]) => "="),
96 (pub struct EqEq([Span; 2]) => "=="),
97 (pub struct Ge([Span; 2]) => ">="),
98 (pub struct Gt([Span; 1]) => ">"),
99 (pub struct Le([Span; 2]) => "<="),
100 (pub struct Lt([Span; 1]) => "<"),
101 (pub struct MulEq([Span; 2]) => "*="),
102 (pub struct Ne([Span; 2]) => "!="),
103 (pub struct Or([Span; 1]) => "|"),
104 (pub struct OrEq([Span; 2]) => "|="),
105 (pub struct OrOr([Span; 2]) => "||"),
106 (pub struct Pound([Span; 1]) => "#"),
107 (pub struct Question([Span; 1]) => "?"),
108 (pub struct RArrow([Span; 2]) => "->"),
109 (pub struct Rem([Span; 1]) => "%"),
110 (pub struct RemEq([Span; 2]) => "%="),
111 (pub struct Rocket([Span; 2]) => "=>"),
112 (pub struct Semi([Span; 1]) => ";"),
113 (pub struct Shl([Span; 2]) => "<<"),
114 (pub struct ShlEq([Span; 3]) => "<<="),
115 (pub struct Shr([Span; 2]) => ">>"),
116 (pub struct ShrEq([Span; 3]) => ">>="),
117 (pub struct Star([Span; 1]) => "*"),
118 (pub struct Sub([Span; 1]) => "-"),
119 (pub struct SubEq([Span; 2]) => "-="),
120 (pub struct Underscore([Span; 1]) => "_"),
121 }
122 delim: {
123 (pub struct Brace => "{"),
124 (pub struct Bracket => "["),
125 (pub struct Paren => "("),
126 }
127 syms: {
128 (pub struct As => "as"),
129 (pub struct Box => "box"),
130 (pub struct Break => "break"),
131 (pub struct Catch => "catch"),
132 (pub struct Const => "const"),
133 (pub struct Continue => "continue"),
134 (pub struct Crate => "crate"),
135 (pub struct Default => "default"),
136 (pub struct Do => "do"),
137 (pub struct Else => "else"),
138 (pub struct Enum => "enum"),
139 (pub struct Extern => "extern"),
140 (pub struct Fn => "fn"),
141 (pub struct For => "for"),
142 (pub struct If => "if"),
143 (pub struct Impl => "impl"),
144 (pub struct In => "in"),
145 (pub struct Let => "let"),
146 (pub struct Loop => "loop"),
147 (pub struct Match => "match"),
148 (pub struct Mod => "mod"),
149 (pub struct Move => "move"),
150 (pub struct Mut => "mut"),
151 (pub struct Pub => "pub"),
152 (pub struct Ref => "ref"),
153 (pub struct Return => "return"),
154 (pub struct Self_ => "self"),
155 (pub struct Static => "static"),
156 (pub struct Struct => "struct"),
157 (pub struct Trait => "trait"),
158 (pub struct Type => "type"),
159 (pub struct Union => "union"),
160 (pub struct Unsafe => "unsafe"),
161 (pub struct Use => "use"),
162 (pub struct Where => "where"),
163 (pub struct While => "while"),
164 }
165}
166
167#[cfg(feature = "printing")]
168mod printing {
169 use Span;
170 use proc_macro2::{TokenTree, TokenKind, OpKind};
171 use quote::Tokens;
172
173 pub fn op(s: &str, spans: &[Span], tokens: &mut Tokens) {
174 assert_eq!(s.len(), spans.len());
175
176 let mut chars = s.chars();
177 let mut spans = spans.iter();
178 let ch = chars.next_back().unwrap();
179 let span = spans.next_back().unwrap();
180 for (ch, span) in chars.zip(spans) {
181 tokens.append(TokenTree {
182 span: span.0,
183 kind: TokenKind::Op(ch, OpKind::Joint),
184 });
185 }
186
187 tokens.append(TokenTree {
188 span: span.0,
189 kind: TokenKind::Op(ch, OpKind::Alone),
190 });
191 }
192
193 pub fn sym(s: &str, span: &Span, tokens: &mut Tokens) {
194 tokens.append(TokenTree {
195 span: span.0,
196 kind: TokenKind::Word(s.into()),
197 });
198 }
199
200 pub fn delim<F>(s: &str, span: &Span, tokens: &mut Tokens, f: F)
201 where F: FnOnce(&mut Tokens)
202 {
203 tokens.append_delimited(s, span.0, f)
204 }
205}