syn_error_experiment/
parse.rs

1//! Parsing interface for parsing a token stream into a syntax tree node.
2
3use std::cell::Cell;
4use std::fmt::Display;
5use std::marker::PhantomData;
6use std::mem;
7use std::ops::Deref;
8
9use proc_macro2::{Ident, Span};
10use syn::buffer::Cursor;
11
12use error;
13
14pub use error::{Error, Result};
15pub use lookahead::{Lookahead1, Peek};
16
17/// Parsing interface implemented by all types that can be parsed in a default
18/// way from a token stream.
19pub trait Parse: Sized {
20    fn parse(input: ParseStream) -> Result<Self>;
21}
22
23/// Input to a Syn parser function.
24pub type ParseStream<'a> = &'a ParseBuffer<'a>;
25
26/// Cursor position within a buffered token stream.
27#[derive(Clone)]
28pub struct ParseBuffer<'a> {
29    scope: Span,
30    cell: Cell<Cursor<'static>>,
31    marker: PhantomData<Cursor<'a>>,
32}
33
34// Not public API.
35#[doc(hidden)]
36#[derive(Copy, Clone)]
37pub struct StepCursor<'c, 'a> {
38    scope: Span,
39    cursor: Cursor<'c>,
40    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
41}
42
43impl<'c, 'a> Deref for StepCursor<'c, 'a> {
44    type Target = Cursor<'c>;
45
46    fn deref(&self) -> &Self::Target {
47        &self.cursor
48    }
49}
50
51impl<'c, 'a> StepCursor<'c, 'a> {
52    // Not public API.
53    #[doc(hidden)]
54    pub fn advance(self, other: Cursor<'c>) -> Cursor<'a> {
55        unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(other) }
56    }
57
58    // Not public API.
59    #[doc(hidden)]
60    pub fn error<T: Display>(self, message: T) -> Error {
61        error::new_at(self.scope, self.cursor, message)
62    }
63}
64
65impl<'a> ParseBuffer<'a> {
66    // Not public API.
67    #[doc(hidden)]
68    pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
69        let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
70        ParseBuffer {
71            scope: scope,
72            cell: Cell::new(extend),
73            marker: PhantomData,
74        }
75    }
76
77    pub fn cursor(&self) -> Cursor<'a> {
78        self.cell.get()
79    }
80
81    pub fn is_empty(&self) -> bool {
82        self.cursor().eof()
83    }
84
85    pub fn lookahead1(&self) -> Lookahead1<'a> {
86        Lookahead1::new(self.scope, self.cursor())
87    }
88
89    pub fn parse<T: Parse>(&self) -> Result<T> {
90        T::parse(self)
91    }
92
93    // Not public API.
94    #[doc(hidden)]
95    pub fn step_cursor<F, R>(&self, function: F) -> Result<R>
96    where
97        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
98    {
99        match function(StepCursor {
100            scope: self.scope,
101            cursor: self.cell.get(),
102            marker: PhantomData,
103        }) {
104            Ok((ret, cursor)) => {
105                self.cell.set(cursor);
106                Ok(ret)
107            }
108            Err(err) => Err(err),
109        }
110    }
111}
112
113impl Parse for Ident {
114    fn parse(input: ParseStream) -> Result<Self> {
115        input.step_cursor(|cursor| {
116            if let Some((ident, rest)) = cursor.ident() {
117                Ok((ident, rest))
118            } else {
119                Err(cursor.error("expected identifier"))
120            }
121        })
122    }
123}
124
125// In reality the impl would be for Punctuated.
126impl<T: Parse> Parse for Vec<T> {
127    fn parse(input: ParseStream) -> Result<Self> {
128        let mut vec = Vec::new();
129        while !input.is_empty() {
130            let t = input.parse::<T>()?;
131            vec.push(t);
132        }
133        Ok(vec)
134    }
135}