makepad_micro_proc_macro/
macro_lib.rs

1#![allow(dead_code)]
2extern crate proc_macro;
3use proc_macro::{TokenTree, Span, TokenStream, Delimiter, Group, Literal, Ident, Punct, Spacing};
4use proc_macro::token_stream::IntoIter;
5
6// little macro utility lib
7
8pub fn error_span(err: &str, span: Span) -> TokenStream {
9    let mut tb = TokenBuilder::new();
10    tb.ident_with_span("compile_error", span).add("! (").string(err).add(") ;");
11    tb.end()
12}
13
14pub fn error(err: &str) -> TokenStream {
15    let mut tb = TokenBuilder::new();
16    tb.add("compile_error ! (").string(err).add(") ;");
17    tb.end()
18}
19
20pub fn error_result(err: &str) -> Result<(), TokenStream> {
21    let mut tb = TokenBuilder::new();
22    tb.add("compile_error ! (").string(err).add(") ;");
23    Err(tb.end())
24}
25
26pub fn unwrap_option(input: TokenStream) -> Result<TokenStream, TokenStream> {
27    let mut ty_parser = TokenParser::new(input.clone());
28    if ty_parser.eat_ident("Option") {
29        if !ty_parser.eat_punct_alone('<') {
30            panic!()
31        }
32        Ok(ty_parser.eat_level_or_punct('>'))
33    }
34    else {
35        Err(input)
36    }
37}
38
39pub struct TokenBuilder {
40    pub groups: Vec<(Delimiter, TokenStream)>
41}
42
43impl TokenBuilder {
44    pub fn new() -> Self {
45        Self {
46            groups: vec![(Delimiter::None, TokenStream::new())]
47        }
48    }
49    
50    pub fn is_empty(&self) -> bool {
51        self.groups.len() == 1 && self.groups[0].1.is_empty()
52    }
53    
54    pub fn end(mut self) -> TokenStream {
55        if self.groups.len() != 1 {
56            panic!("Groups not empty, you missed a pop_group")
57        }
58        self.groups.pop().unwrap().1
59    }
60    
61    pub fn eprint(&self) {
62        eprintln!("{}", self.groups.last().unwrap().1.to_string());
63    }
64    
65    pub fn extend(&mut self, tt: TokenTree) -> &mut Self {
66        self.groups.last_mut().unwrap().1.extend(Some(tt));
67        self
68    }
69    
70    pub fn stream(&mut self, what: Option<TokenStream>) -> &mut Self {
71        if let Some(what) = what {
72            for c in what.into_iter() {
73                self.extend(c);
74            }
75            self
76        }
77        else {
78            self
79        }
80    }
81    
82    pub fn add(&mut self, what: &str) -> &mut Self {
83        let b = what.as_bytes();
84        let mut o = 0;
85        while o < b.len() {
86            let c0 = b[o] as char;
87            let c1 = if o + 1 < b.len() {b[o + 1] as char}else {'\0'};
88            match (c0, c1) {
89                ('\r', _) | ('\n', _) | (' ', _) | ('\t', _) => {o += 1;}
90                ('{', _) => {self.push_group(Delimiter::Brace); o += 1;},
91                ('(', _) => {self.push_group(Delimiter::Parenthesis); o += 1;},
92                ('[', _) => {self.push_group(Delimiter::Bracket); o += 1;},
93                ('}', _) => {self.pop_group(Delimiter::Brace); o += 1;},
94                (')', _) => {self.pop_group(Delimiter::Parenthesis); o += 1;},
95                (']', _) => {self.pop_group(Delimiter::Bracket); o += 1;},
96                ('<', '<') | ('>', '>') | ('&', '&') | ('|', '|') |
97                ('-', '>') | ('=', '>') |
98                ('<', '=') | ('>', '=') | ('=', '=') | ('!', '=') | (':', ':') |
99                ('+', '=') | ('-', '=') | ('*', '=') | ('/', '=') | ('.', '.') => {
100                    self.punct(std::str::from_utf8(&b[o..o + 2]).unwrap());
101                    o += 2;
102                }
103                ('+', _) | ('-', _) | ('*', _) | ('/', _) | ('#', _) |
104                ('=', _) | ('<', _) | ('>', _) | ('?', _) | (';', _) | ('&', _) |
105                ('^', _) | (':', _) | (',', _) | ('!', _) | ('.', _) | ('|', _) => {
106                    self.punct(std::str::from_utf8(&b[o..o + 1]).unwrap());
107                    o += 1;
108                },
109                ('0', 'x') => { // this needs to be fancier but whatever.
110                    let mut e = o + 2;
111                    let mut out: u64 = 0;
112                    while e < b.len() {
113                        match b[e] {
114                            b'0'..=b'9' => out = (out << 4) | (b[e] - b'0') as u64,
115                            b'a'..=b'f' => out = (out << 4) | (b[e] - b'a' + 10) as u64,
116                            b'A'..=b'F' => out = (out << 4) | (b[e] - b'A' + 10) as u64,
117                            b'_' => (),
118                            _ => break,
119                        };
120                        e += 1;
121                    }
122                    self.suf_u64(out);
123                    o = e;
124                }
125                ('0'..='9', _) => {
126                    let mut e = o + 1;
127                    while e < b.len() {
128                        match b[e] {
129                            b'0'..=b'9' => e += 1,
130                            _ => break,
131                        }
132                    }
133                    let num = std::str::from_utf8(&b[o..e]).unwrap();
134                    self.unsuf_usize(num.parse().unwrap_or_else(|_| panic!("Can't parse usize number \"{}\"", what)));
135                    o = e;
136                }
137                ('"', _) => {
138                    let mut e = o + 1;
139                    while e < b.len() {
140                        match b[e] {
141                            b'"' => break,
142                            _ => e += 1,
143                        }
144                    }
145                    self.string(std::str::from_utf8(&b[o + 1..e]).unwrap());
146                    o = e + 1;
147                }
148                ('\'', _) => {
149                    let mut e = o + 1;
150                    while e < b.len() {
151                        match b[e] {
152                            b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' => e += 1,
153                            _ => break,
154                        }
155                    }
156                    if o == e {
157                        panic!("Unexpected character {:?}", b[e] as char);
158                    }
159                    let ident = std::str::from_utf8(&b[o + 1..e]).unwrap();
160                    self.lifetime_mark();
161                    self.ident(ident);
162                    o = e;
163                }
164                _ => {
165                    let mut e = o;
166                    while e < b.len() {
167                        match b[e] {
168                            b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' => e += 1,
169                            _ => break,
170                        }
171                    }
172                    if o == e {
173                        panic!("Unexpected character {:?}", b[e] as char);
174                    }
175                    let ident = std::str::from_utf8(&b[o..e]).unwrap();
176                    self.ident(ident);
177                    o = e;
178                }
179            }
180        }
181        self
182    }
183    
184    pub fn ident(&mut self, id: &str) -> &mut Self {
185        self.extend(TokenTree::from(Ident::new(id, Span::call_site())))
186    }
187    
188    pub fn ident_with_span(&mut self, id: &str, span: Span) -> &mut Self {
189        self.extend(TokenTree::from(Ident::new(id, span)))
190    }
191    
192    pub fn punct(&mut self, s: &str) -> &mut Self {
193        for (last, c) in s.chars().identify_last() {
194            self.extend(TokenTree::from(Punct::new(c, if last {Spacing::Alone} else {Spacing::Joint})));
195        }
196        self
197    }
198    
199    pub fn lifetime_mark(&mut self) -> &mut Self {
200        self.extend(TokenTree::from(Punct::new('\'', Spacing::Joint)));
201        self
202    }
203    
204    pub fn sep(&mut self) -> &mut Self {
205        self.extend(TokenTree::from(Punct::new(':', Spacing::Joint)));
206        self.extend(TokenTree::from(Punct::new(':', Spacing::Alone)));
207        self
208    }
209    
210    pub fn string(&mut self, val: &str) -> &mut Self {self.extend(TokenTree::from(Literal::string(val)))}
211    pub fn unsuf_usize(&mut self, val: usize) -> &mut Self {self.extend(TokenTree::from(Literal::usize_unsuffixed(val)))}
212    pub fn suf_u16(&mut self, val: u16) -> &mut Self {self.extend(TokenTree::from(Literal::u16_suffixed(val)))}
213    pub fn suf_u32(&mut self, val: u32) -> &mut Self {self.extend(TokenTree::from(Literal::u32_suffixed(val)))}
214    pub fn suf_u64(&mut self, val: u64) -> &mut Self {self.extend(TokenTree::from(Literal::u64_suffixed(val)))}
215    pub fn unsuf_f32(&mut self, val: f32) -> &mut Self {self.extend(TokenTree::from(Literal::f32_unsuffixed(val)))}
216    pub fn unsuf_f64(&mut self, val: f64) -> &mut Self {self.extend(TokenTree::from(Literal::f64_unsuffixed(val)))}
217    pub fn unsuf_i64(&mut self, val: i64) -> &mut Self {self.extend(TokenTree::from(Literal::i64_unsuffixed(val)))}
218    
219    pub fn chr(&mut self, val: char) -> &mut Self {self.extend(TokenTree::from(Literal::character(val)))}
220    pub fn _lit(&mut self, lit: Literal) -> &mut Self {self.extend(TokenTree::from(lit))}
221    
222    pub fn push_group(&mut self, delim: Delimiter) -> &mut Self {
223        self.groups.push((delim, TokenStream::new()));
224        self
225    }
226    
227    pub fn stack_as_string(&self) -> String {
228        let mut ret = String::new();
229        for i in (0..self.groups.len() - 1).rev() {
230            ret.push_str(&format!("Level {}: {}", i, self.groups[i].1.to_string()));
231        }
232        ret
233    }
234    
235    pub fn pop_group(&mut self, delim: Delimiter) -> &mut Self {
236        if self.groups.len() < 2 {
237            eprintln!("Stack dump for error:\n{}", self.stack_as_string());
238            panic!("pop_group stack is empty {}", self.groups.len());
239        }
240        let ts = self.groups.pop().unwrap();
241        if ts.0 != delim {
242            eprintln!("Stack dump for error:\n{}", self.stack_as_string());
243            panic!("pop_group Delimiter mismatch, got {:?} expected {:?}", ts.0, delim);
244        }
245        self.extend(TokenTree::from(Group::new(delim, ts.1)));
246        self
247    }
248}
249
250impl Default for TokenBuilder {
251    fn default() -> Self {
252        Self::new()
253    }
254}
255
256pub trait IdentifyLast: Iterator + Sized {
257    fn identify_last(self) -> Iter<Self>;
258}
259
260impl<It> IdentifyLast for It where It: Iterator {
261    fn identify_last(mut self) -> Iter<Self> {
262        let e = self.next();
263        Iter {
264            iter: self,
265            buffer: e,
266        }
267    }
268}
269
270pub struct Iter<It> where It: Iterator {
271    iter: It,
272    buffer: Option<It::Item>,
273}
274
275#[derive(Debug)]
276pub struct Attribute {
277    pub name: String,
278    pub args: Option<TokenStream>
279}
280
281pub struct StructField {
282    pub name: String,
283    pub ty: TokenStream,
284    pub attrs: Vec<Attribute>
285}
286
287impl<It> Iterator for Iter<It> where It: Iterator {
288    type Item = (bool, It::Item);
289    
290    fn next(&mut self) -> Option<Self::Item> {
291        match self.buffer.take() {
292            None => None,
293            Some(e) => {
294                match self.iter.next() {
295                    None => Some((true, e)),
296                    Some(f) => {
297                        self.buffer = Some(f);
298                        Some((false, e))
299                    },
300                }
301            },
302        }
303    }
304}
305
306pub struct TokenParser {
307    iter_stack: Vec<IntoIter>,
308    pub current: Option<TokenTree>
309}
310
311// this parser is optimized for parsing type definitions, not general Rust code
312
313impl TokenParser {
314    pub fn new(start: TokenStream) -> Self {
315        let mut ret = Self {iter_stack: vec![start.into_iter()], current: None};
316        ret.advance();
317        ret
318    }
319    
320    pub fn advance(&mut self) {
321        let last = self.iter_stack.last_mut().unwrap();
322        let value = last.next();
323        if let Some(tok) = value {
324            self.current = Some(tok);
325        }
326        else {
327            self.current = None;
328        }
329        // skip over ///
330        
331    }
332    
333    pub fn unexpected(&self) -> TokenStream {
334        error("Unexpected token")
335    }
336    
337    pub fn is_delim(&mut self, delim: Delimiter) -> bool {
338        if let Some(TokenTree::Group(group)) = &self.current {
339            group.delimiter() == delim
340        }
341        else {
342            false
343        }
344    }
345    
346    pub fn is_brace(&mut self) -> bool {
347        self.is_delim(Delimiter::Brace)
348    }
349    
350    pub fn is_paren(&mut self) -> bool {
351        self.is_delim(Delimiter::Parenthesis)
352    }
353    
354    pub fn is_bracket(&mut self) -> bool {
355        self.is_delim(Delimiter::Bracket)
356    }
357    
358    pub fn open_delim(&mut self, delim: Delimiter) -> bool {
359        if let Some(TokenTree::Group(group)) = &self.current {
360            if group.delimiter() == delim {
361                self.iter_stack.push(group.stream().into_iter());
362                self.advance();
363                return true
364            }
365        }
366        false
367    }
368    
369    pub fn is_group_with_delim(&mut self, delim: Delimiter) -> bool {
370        if let Some(TokenTree::Group(group)) = &self.current {
371            delim == group.delimiter()
372        }
373        else {
374            false
375        }
376    }
377    
378    pub fn open_group(&mut self) -> Option<Delimiter> {
379        if let Some(TokenTree::Group(group)) = &self.current {
380            let delim = group.delimiter();
381            self.iter_stack.push(group.stream().into_iter());
382            self.advance();
383            return Some(delim)
384        }
385        None
386    }
387    
388    pub fn open_brace(&mut self) -> bool {
389        self.open_delim(Delimiter::Brace)
390    }
391    
392    pub fn open_paren(&mut self) -> bool {
393        self.open_delim(Delimiter::Parenthesis)
394    }
395    
396    pub fn open_bracket(&mut self) -> bool {
397        self.open_delim(Delimiter::Bracket)
398    }
399    
400    pub fn is_eot(&mut self) -> bool {
401        self.current.is_none() && !self.iter_stack.is_empty()
402    }
403    
404    pub fn eat_eot(&mut self) -> bool {
405        // current is None
406        if self.is_eot() {
407            self.iter_stack.pop();
408            if !self.iter_stack.is_empty() {
409                self.advance()
410            }
411            return true;
412        }
413        false
414    }
415    
416    pub fn eat_level(&mut self) -> TokenStream {
417        let mut tb = TokenBuilder::new();
418        while !self.eat_eot() {
419            tb.extend(self.current.clone().unwrap());
420            self.advance();
421        }
422        tb.end()
423    }
424    
425    pub fn eat_level_or_punct(&mut self, what: char) -> TokenStream {
426        let mut tb = TokenBuilder::new();
427        while !self.eat_eot() {
428            if self.is_punct_alone(what) {
429                self.advance();
430                return tb.end();
431            }
432            tb.extend(self.current.clone().unwrap());
433            self.advance();
434        }
435        tb.end()
436    }
437    
438    pub fn eat_ident(&mut self, what: &str) -> bool {
439        // check if our current thing is an ident, ifso eat it.
440        if let Some(TokenTree::Ident(ident)) = &self.current {
441            if ident.to_string() == what {
442                self.advance();
443                return true
444            }
445        }
446        false
447    }
448    
449    pub fn is_literal(&mut self) -> bool {
450        // check if our current thing is an ident, ifso eat it.
451        if let Some(TokenTree::Literal(_)) = &self.current {
452            return true
453        }
454        false
455    }
456    
457    pub fn eat_literal(&mut self) -> Option<Literal> {
458        // check if our current thing is an ident, ifso eat it.
459        if let Some(TokenTree::Literal(lit)) = &self.current {
460            let ret = Some(lit.clone());
461            self.advance();
462            return ret
463        }
464        None
465    }
466    
467    pub fn span(&self) -> Option<Span> {
468        self.current.as_ref().map(|current| current.span())
469    }
470    
471    pub fn is_punct_alone(&mut self, what: char) -> bool {
472        // check if our punct is multichar.
473        if let Some(TokenTree::Punct(current)) = &self.current {
474            if current.as_char() == what && (current.as_char() == '>' || current.spacing() == Spacing::Alone) {
475                return true
476            }
477        }
478        false
479    }
480    
481    pub fn is_punct_any(&mut self, what: char) -> bool {
482        // check if our punct is multichar.
483        if let Some(TokenTree::Punct(current)) = &self.current {
484            if current.as_char() == what {
485                return true
486            }
487        }
488        false
489    }
490    
491    
492    pub fn eat_double_colon_destruct(&mut self) -> bool {
493        // check if our punct is multichar.
494        if let Some(TokenTree::Punct(current)) = &self.current {
495            if current.as_char() == ':' && current.spacing() == Spacing::Joint {
496                self.advance();
497                if let Some(TokenTree::Punct(current)) = &self.current {
498                    if current.as_char() == ':' && current.spacing() == Spacing::Alone {
499                        self.advance();
500                        return true
501                    }
502                }
503            }
504        }
505        false
506    }
507    
508    pub fn eat_sep(&mut self) -> bool {
509        // check if our punct is multichar.
510        if let Some(TokenTree::Punct(current)) = &self.current {
511            if current.as_char() == ':' && current.spacing() == Spacing::Joint {
512                self.advance();
513                if let Some(TokenTree::Punct(current)) = &self.current {
514                    if current.as_char() == ':' && current.spacing() == Spacing::Alone {
515                        self.advance();
516                        return true
517                    }
518                }
519            }
520        }
521        false
522    }
523    
524    pub fn eat_punct_alone(&mut self, what: char) -> bool {
525        if self.is_punct_alone(what) {
526            self.advance();
527            return true
528        }
529        false
530    }
531    
532    pub fn eat_punct_any(&mut self, what: char) -> bool {
533        if self.is_punct_any(what) {
534            self.advance();
535            return true
536        }
537        false
538    }
539    
540    pub fn eat_any_punct(&mut self) -> Option<String> {
541        let mut out = String::new();
542        while let Some(TokenTree::Punct(current)) = &self.current {
543            out.push(current.as_char());
544            if current.spacing() == Spacing::Alone {
545                self.advance();
546                return Some(out);
547            }
548            self.advance();
549        }
550        None
551    }
552    
553    pub fn eat_any_ident(&mut self) -> Option<String> {
554        if let Some(TokenTree::Ident(ident)) = &self.current {
555            let ret = Some(ident.to_string());
556            self.advance();
557            return ret
558        }
559        None
560    }
561    
562    pub fn eat_any_ident_with_span(&mut self) -> Option<(String, Span)> {
563        if let Some(TokenTree::Ident(ident)) = &self.current {
564            let ret = Some((ident.to_string(), self.span().unwrap()));
565            self.advance();
566            return ret
567        }
568        None
569    }
570    
571    pub fn expect_any_ident(&mut self) -> Result<String, TokenStream> {
572        if let Some(TokenTree::Ident(ident)) = &self.current {
573            let ret = ident.to_string();
574            self.advance();
575            return Ok(ret)
576        }
577        Err(error("Expected any ident"))
578    }
579    
580    
581    pub fn expect_punct_alone(&mut self, what: char) -> Result<(), TokenStream> {
582        if self.is_punct_alone(what) {
583            self.advance();
584            Ok(())
585        }
586        else {
587            Err(error(&format!("Expected punct {}", what)))
588        }
589    }
590    
591    pub fn expect_punct_any(&mut self, what: char) -> Result<(), TokenStream> {
592        if self.is_punct_any(what) {
593            self.advance();
594            Ok(())
595        }
596        else {
597            Err(error(&format!("Expected punct {}", what)))
598        }
599    }
600    
601    pub fn eat_ident_path(&mut self) -> Option<TokenStream> {
602        let mut tb = TokenBuilder::new();
603        while let Some(ident) = self.eat_any_ident() {
604            tb.ident(&ident);
605            if !self.eat_sep() {
606                break
607            }
608            tb.sep();
609        }
610
611        let ts = tb.end();
612        if !ts.is_empty() {
613            return Some(ts)
614        }
615        None
616    }
617    
618    pub fn eat_where_clause(&mut self, add_where: Option<&str>) -> Option<TokenStream> {
619        let mut tb = TokenBuilder::new();
620        if self.eat_ident("where") {
621            tb.add("where");
622            // ok now we parse an ident
623            loop {
624                if let Some(ident) = self.eat_any_ident() {
625                    tb.ident(&ident);
626                    tb.stream(self.eat_generic());
627                    
628                    if !self.eat_punct_alone(':') {
629                        return None
630                    }
631                    tb.add(":");
632                    loop {
633                        if let Some(ident) = self.eat_any_ident() {
634                            tb.add(&ident);
635                            tb.stream(self.eat_generic());
636                            // check if we have upnext
637                            // {, + or ,
638                            if self.eat_punct_alone('+') {
639                                tb.add("+");
640                                continue
641                            }
642                            if self.eat_punct_alone(',') { // next one
643                                if let Some(add_where) = add_where {
644                                    tb.add("+");
645                                    tb.ident(add_where);
646                                }
647                                tb.add(",");
648                                break
649                            }
650                            if self.is_brace() || self.is_punct_alone(';') { // upnext is a brace.. we're done
651                                if let Some(add_where) = add_where {
652                                    tb.add("+");
653                                    tb.ident(add_where);
654                                }
655                                return Some(tb.end())
656                            }
657                        }
658                        else {
659                            return None // unexpected
660                        }
661                    }
662                }
663                else {
664                    return None // unexpected
665                }
666            }
667        }
668        None
669    }
670    
671    pub fn eat_struct_field(&mut self) -> Option<StructField> {
672        // letsparse an ident
673        let attrs = self.eat_attributes();
674        
675        self.eat_ident("pub");
676        if let Some(field) = self.eat_any_ident() {
677            if self.eat_punct_alone(':') {
678                if let Some(ty) = self.eat_type() {
679                    return Some(StructField {name: field, ty, attrs})
680                }
681            }
682        }
683        None
684    }
685    
686    pub fn eat_attributes(&mut self) -> Vec<Attribute> {
687        let mut results = Vec::new();
688        while self.eat_punct_alone('#') { // parse our attribute
689            if !self.open_bracket() {
690                break;
691            }
692            let mut assign_form = false;
693            while let Some(ident) = self.eat_any_ident() {
694                // we might have an =
695                if self.eat_punct_alone('=') {
696                    let level = self.eat_level();
697                    results.push(Attribute {name: ident, args: Some(level)});
698                    //eprintln!("{} {}", results.last().unwrap().name, results.last().as_ref().unwrap().args.as_ref().unwrap().to_string());
699                    assign_form = true;
700                    break;
701                }
702                if !self.open_paren() && !self.open_brace() {
703                    results.push(Attribute {name: ident, args: None});
704                    break;
705                }
706                // lets take the whole ts
707                results.push(Attribute {name: ident, args: Some(self.eat_level())});
708                self.eat_punct_alone(',');
709            }
710            if !assign_form && !self.eat_eot() {
711                break
712            }
713        }
714        results
715    }
716    
717    pub fn eat_all_struct_fields(&mut self,) -> Option<Vec<StructField >> {
718        
719        if self.open_brace() {
720            let mut fields = Vec::new();
721            while !self.eat_eot() {
722                // lets eat an attrib
723                if let Some(sf) = self.eat_struct_field() {
724                    fields.push(sf);
725                    self.eat_punct_alone(',');
726                }
727                else {
728                    return None
729                }
730            }
731            return Some(fields)
732        }
733        None
734    }
735    
736    
737    pub fn eat_generic(&mut self) -> Option<TokenStream> {
738        let mut tb = TokenBuilder::new();
739        // if we have a <, keep running and keep a < stack
740        
741        if self.eat_punct_alone('<') {
742            tb.add("<");
743            let mut stack = 1;
744            // keep eating things till we are at stack 0 for a ">"
745            while stack > 0 {
746                if self.eat_punct_alone('<') {
747                    tb.add("<");
748                    stack += 1;
749                }
750                if self.eat_punct_alone('>') {
751                    tb.add(">");
752                    stack -= 1;
753                }
754                else if self.eat_eot() { // shits broken
755                    return None
756                }
757                else { // store info here in generics struct
758                    if let Some(current) = &self.current {
759                        tb.extend(current.clone());
760                    }
761                    self.advance();
762                }
763            }
764            
765            return Some(tb.end())
766        }
767        None
768    }
769    
770    pub fn eat_all_types(&mut self) -> Option<Vec<TokenStream >> {
771        if self.open_paren() {
772            let mut ret = Vec::new();
773            while !self.eat_eot() {
774                self.eat_ident("pub");
775                if let Some(tt) = self.eat_type() {
776                    ret.push(tt);
777                    self.eat_punct_alone(',');
778                }
779                else {
780                    return None
781                }
782            }
783            Some(ret)
784        }
785        else {
786            None
787        }
788    }
789    
790    pub fn eat_type(&mut self) -> Option<TokenStream> {
791        let mut tb = TokenBuilder::new();
792        if self.eat_punct_alone('&'){
793            tb.add("&");
794            if self.eat_punct_any('\''){
795                tb.lifetime_mark();
796                if let Some((ty, span)) = self.eat_any_ident_with_span() {
797                    tb.ident_with_span(&ty, span);
798                }
799            }
800        }
801        if self.open_bracket() { // array type
802            tb.add("[");
803            while !self.eat_eot() {
804                if let Some(current) = &self.current {
805                    tb.extend(current.clone());
806                }
807                self.advance();
808            }
809            tb.add("]");
810            return Some(tb.end())
811        }
812        else if self.open_paren() { // tuple type
813            tb.add("(");
814            while !self.eat_eot() {
815                tb.stream(self.eat_type());
816                self.eat_punct_alone(',');
817            }
818            tb.add(")");
819            return Some(tb.end());
820        }
821        else if let Some((ty, span)) = self.eat_any_ident_with_span() {
822            tb.ident_with_span(&ty, span);
823            if ty == "dyn" {
824                if let Some((ty, span)) = self.eat_any_ident_with_span() {
825                    tb.ident_with_span(&ty, span);
826                }
827            }
828            tb.stream(self.eat_generic());
829            return Some(tb.end())
830        }
831        None
832    }
833    
834}
835