swc_ecma_lexer/common/parser/
buffer.rs

1use swc_atoms::Atom;
2use swc_common::{BytePos, Span};
3use swc_ecma_ast::EsVersion;
4
5use super::token_and_span::TokenAndSpan as TokenAndSpanTrait;
6use crate::common::{
7    context::Context,
8    input::Tokens,
9    lexer::{token::TokenFactory, LexResult},
10    syntax::SyntaxFlags,
11};
12
13pub trait NextTokenAndSpan {
14    type Token;
15    fn token(&self) -> &Self::Token;
16    fn span(&self) -> Span;
17    fn had_line_break(&self) -> bool;
18}
19
20pub trait Buffer<'a> {
21    type Token: std::fmt::Debug + PartialEq + Clone + TokenFactory<'a, Self::TokenAndSpan, Self::I>;
22    type Next: NextTokenAndSpan<Token = Self::Token>;
23    type TokenAndSpan: TokenAndSpanTrait<Token = Self::Token>;
24    type I: Tokens<Self::TokenAndSpan>;
25
26    fn new(lexer: Self::I) -> Self;
27    fn iter(&self) -> &Self::I;
28    fn iter_mut(&mut self) -> &mut Self::I;
29
30    fn set_cur(&mut self, token: Self::TokenAndSpan);
31    fn next(&self) -> Option<&Self::Next>;
32    fn set_next(&mut self, token: Option<Self::Next>);
33    fn next_mut(&mut self) -> &mut Option<Self::Next>;
34
35    fn cur(&self) -> &Self::Token;
36    fn get_cur(&self) -> &Self::TokenAndSpan;
37
38    fn prev_span(&self) -> Span;
39
40    fn peek<'b>(&'b mut self) -> Option<&'b Self::Token>
41    where
42        Self::TokenAndSpan: 'b;
43
44    fn store(&mut self, token: Self::Token) {
45        debug_assert!(self.next().is_none());
46        debug_assert!(!self.cur().is_eof());
47        let span = self.prev_span();
48        let token = Self::TokenAndSpan::new(token, span, false);
49        self.set_cur(token);
50    }
51
52    fn dump_cur(&self) -> String;
53
54    /// find next token.
55    fn bump(&mut self);
56    fn expect_word_token_and_bump(&mut self) -> Atom;
57    fn expect_number_token_and_bump(&mut self) -> (f64, Atom);
58    fn expect_string_token_and_bump(&mut self) -> (Atom, Atom);
59    fn expect_bigint_token_and_bump(&mut self) -> (Box<num_bigint::BigInt>, Atom);
60    fn expect_regex_token_and_bump(&mut self) -> (Atom, Atom);
61    fn expect_template_token_and_bump(&mut self) -> (LexResult<Atom>, Atom);
62    fn expect_error_token_and_bump(&mut self) -> crate::error::Error;
63    fn expect_jsx_name_token_and_bump(&mut self) -> Atom;
64    fn expect_jsx_text_token_and_bump(&mut self) -> (Atom, Atom);
65    fn expect_shebang_token_and_bump(&mut self) -> Atom;
66
67    fn had_line_break_before_cur(&self) -> bool {
68        self.get_cur().had_line_break()
69    }
70
71    /// This returns true on eof.
72    fn has_linebreak_between_cur_and_peeked(&mut self) -> bool {
73        let _ = self.peek();
74        self.next().map(|item| item.had_line_break()).unwrap_or({
75            // return true on eof.
76            true
77        })
78    }
79
80    fn cut_lshift(&mut self) {
81        debug_assert!(
82            self.is(&Self::Token::LSHIFT),
83            "parser should only call cut_lshift when encountering LShift token"
84        );
85        let span = self.cur_span().with_lo(self.cur_span().lo + BytePos(1));
86        let token = Self::TokenAndSpan::new(Self::Token::LESS, span, false);
87        self.set_cur(token);
88    }
89
90    fn merge_lt_gt(&mut self) {
91        debug_assert!(
92            self.is(&Self::Token::LESS) || self.is(&Self::Token::GREATER),
93            "parser should only call merge_lt_gt when encountering Less token"
94        );
95        if self.peek().is_none() {
96            return;
97        }
98        let span = self.cur_span();
99        let next = self.next().unwrap();
100        if span.hi != next.span().lo {
101            return;
102        }
103        let next = self.next_mut().take().unwrap();
104        let cur = self.get_cur();
105        let cur_token = cur.token();
106        let token = if cur_token.is_greater() {
107            let next_token = next.token();
108            if next_token.is_greater() {
109                // >>
110                Self::Token::RSHIFT
111            } else if next_token.is_equal() {
112                // >=
113                Self::Token::GREATER_EQ
114            } else if next_token.is_rshift() {
115                // >>>
116                Self::Token::ZERO_FILL_RSHIFT
117            } else if next_token.is_greater_eq() {
118                // >>=
119                Self::Token::RSHIFT_EQ
120            } else if next_token.is_rshift_eq() {
121                // >>>=
122                Self::Token::ZERO_FILL_RSHIFT_EQ
123            } else {
124                self.set_next(Some(next));
125                return;
126            }
127        } else if cur_token.is_less() {
128            let next_token = next.token();
129            if next_token.is_less() {
130                // <<
131                Self::Token::LSHIFT
132            } else if next_token.is_equal() {
133                // <=
134                Self::Token::LESS_EQ
135            } else if next_token.is_less_eq() {
136                // <<=
137                Self::Token::LSHIFT_EQ
138            } else {
139                self.set_next(Some(next));
140                return;
141            }
142        } else {
143            self.set_next(Some(next));
144            return;
145        };
146        let span = span.with_hi(next.span().hi);
147        let token = Self::TokenAndSpan::new(token, span, cur.had_line_break());
148        self.set_cur(token);
149    }
150
151    #[inline(always)]
152    fn is(&self, expected: &Self::Token) -> bool {
153        self.cur() == expected
154    }
155
156    #[inline(always)]
157    fn eat(&mut self, expected: &Self::Token) -> bool {
158        let v = self.is(expected);
159        if v {
160            self.bump();
161        }
162        v
163    }
164
165    /// Returns start of current token.
166    #[inline]
167    fn cur_pos(&self) -> BytePos {
168        self.get_cur().span().lo
169    }
170
171    #[inline]
172    fn cur_span(&self) -> Span {
173        self.get_cur().span()
174    }
175
176    /// Returns last byte position of previous token.
177    #[inline]
178    fn last_pos(&self) -> BytePos {
179        self.prev_span().hi
180    }
181
182    #[inline]
183    fn get_ctx(&self) -> Context {
184        self.iter().ctx()
185    }
186
187    #[inline]
188    fn update_ctx(&mut self, f: impl FnOnce(&mut Context)) {
189        let ctx = self.iter_mut().ctx_mut();
190        f(ctx)
191    }
192
193    #[inline]
194    fn set_ctx(&mut self, ctx: Context) {
195        self.iter_mut().set_ctx(ctx);
196    }
197
198    #[inline]
199    fn syntax(&self) -> SyntaxFlags {
200        self.iter().syntax()
201    }
202
203    #[inline]
204    fn target(&self) -> EsVersion {
205        self.iter().target()
206    }
207
208    #[inline]
209    fn set_expr_allowed(&mut self, allow: bool) {
210        self.iter_mut().set_expr_allowed(allow)
211    }
212
213    #[inline]
214    fn set_next_regexp(&mut self, start: Option<BytePos>) {
215        self.iter_mut().set_next_regexp(start);
216    }
217
218    #[inline]
219    fn token_context<'b>(&'b self) -> &'b crate::lexer::TokenContexts
220    where
221        Self::I: 'b,
222    {
223        self.iter().token_context()
224    }
225
226    #[inline]
227    fn token_context_mut<'b>(&'b mut self) -> &'b mut crate::lexer::TokenContexts
228    where
229        Self::I: 'b,
230    {
231        self.iter_mut().token_context_mut()
232    }
233
234    #[inline]
235    fn set_token_context(&mut self, c: crate::lexer::TokenContexts) {
236        self.iter_mut().set_token_context(c);
237    }
238
239    #[inline]
240    fn end_pos(&self) -> BytePos {
241        self.iter().end_pos()
242    }
243
244    #[inline]
245    fn token_flags(&self) -> crate::lexer::TokenFlags {
246        self.iter().token_flags()
247    }
248}