swc_ecma_parser/lexer/
capturing.rs

1use std::mem;
2
3use crate::{
4    error::Error,
5    input::Tokens,
6    lexer::{token::TokenAndSpan, TokenFlags},
7    syntax::SyntaxFlags,
8    Context,
9};
10
11#[derive(Debug)]
12pub struct Capturing<I> {
13    inner: I,
14    captured: Vec<TokenAndSpan>,
15}
16
17pub struct CapturingCheckpoint<I: Tokens> {
18    pos: usize,
19    inner: I::Checkpoint,
20}
21
22impl<I: Clone> Clone for Capturing<I> {
23    fn clone(&self) -> Self {
24        Capturing {
25            inner: self.inner.clone(),
26            captured: self.captured.clone(),
27        }
28    }
29}
30
31impl<I> Capturing<I> {
32    pub fn new(input: I) -> Self {
33        Capturing {
34            inner: input,
35            captured: Default::default(),
36        }
37    }
38
39    pub fn tokens(&self) -> &[TokenAndSpan] {
40        &self.captured
41    }
42
43    /// Take captured tokens
44    pub fn take(&mut self) -> Vec<TokenAndSpan> {
45        mem::take(&mut self.captured)
46    }
47
48    fn capture(&mut self, ts: TokenAndSpan) {
49        let v = &mut self.captured;
50
51        // remove tokens that could change due to backtracing
52        while let Some(last) = v.last() {
53            if last.span.lo >= ts.span.lo {
54                v.pop();
55            } else {
56                break;
57            }
58        }
59
60        v.push(ts);
61    }
62}
63
64impl<I: Iterator<Item = TokenAndSpan>> Iterator for Capturing<I> {
65    type Item = TokenAndSpan;
66
67    fn next(&mut self) -> Option<Self::Item> {
68        let next = self.inner.next();
69
70        match next {
71            Some(ts) => {
72                self.capture(ts);
73                Some(ts)
74            }
75            None => None,
76        }
77    }
78}
79
80impl<I: Tokens> Tokens for Capturing<I> {
81    type Checkpoint = CapturingCheckpoint<I>;
82
83    fn checkpoint_save(&self) -> Self::Checkpoint {
84        Self::Checkpoint {
85            pos: self.captured.len(),
86            inner: self.inner.checkpoint_save(),
87        }
88    }
89
90    fn checkpoint_load(&mut self, checkpoint: Self::Checkpoint) {
91        self.captured.truncate(checkpoint.pos);
92        self.inner.checkpoint_load(checkpoint.inner);
93    }
94
95    fn set_ctx(&mut self, ctx: Context) {
96        self.inner.set_ctx(ctx);
97    }
98
99    fn ctx(&self) -> Context {
100        self.inner.ctx()
101    }
102
103    fn ctx_mut(&mut self) -> &mut Context {
104        self.inner.ctx_mut()
105    }
106
107    fn syntax(&self) -> SyntaxFlags {
108        self.inner.syntax()
109    }
110
111    fn target(&self) -> swc_ecma_ast::EsVersion {
112        self.inner.target()
113    }
114
115    fn set_expr_allowed(&mut self, allow: bool) {
116        self.inner.set_expr_allowed(allow);
117    }
118
119    fn set_next_regexp(&mut self, start: Option<swc_common::BytePos>) {
120        self.inner.set_next_regexp(start);
121    }
122
123    fn add_error(&mut self, error: Error) {
124        self.inner.add_error(error);
125    }
126
127    fn add_module_mode_error(&mut self, error: Error) {
128        self.inner.add_module_mode_error(error);
129    }
130
131    fn end_pos(&self) -> swc_common::BytePos {
132        self.inner.end_pos()
133    }
134
135    fn take_errors(&mut self) -> Vec<Error> {
136        self.inner.take_errors()
137    }
138
139    fn take_script_module_errors(&mut self) -> Vec<Error> {
140        self.inner.take_script_module_errors()
141    }
142
143    fn update_token_flags(&mut self, f: impl FnOnce(&mut TokenFlags)) {
144        self.inner.update_token_flags(f);
145    }
146
147    fn token_flags(&self) -> TokenFlags {
148        self.inner.token_flags()
149    }
150
151    fn clone_token_value(&self) -> Option<super::TokenValue> {
152        self.inner.clone_token_value()
153    }
154
155    fn take_token_value(&mut self) -> Option<super::TokenValue> {
156        self.inner.take_token_value()
157    }
158
159    fn get_token_value(&self) -> Option<&super::TokenValue> {
160        self.inner.get_token_value()
161    }
162
163    fn set_token_value(&mut self, token_value: Option<super::TokenValue>) {
164        self.inner.set_token_value(token_value);
165    }
166
167    fn scan_jsx_token(&mut self, allow_multiline_jsx_text: bool) -> TokenAndSpan {
168        self.inner.scan_jsx_token(allow_multiline_jsx_text)
169    }
170
171    fn scan_jsx_open_el_terminal_token(&mut self) -> TokenAndSpan {
172        self.inner.scan_jsx_open_el_terminal_token()
173    }
174
175    fn rescan_jsx_open_el_terminal_token(&mut self, reset: swc_common::BytePos) -> TokenAndSpan {
176        let ts = self.inner.rescan_jsx_open_el_terminal_token(reset);
177        self.capture(ts);
178        ts
179    }
180
181    fn rescan_jsx_token(
182        &mut self,
183        allow_multiline_jsx_text: bool,
184        reset: swc_common::BytePos,
185    ) -> TokenAndSpan {
186        let ts = self.inner.rescan_jsx_token(allow_multiline_jsx_text, reset);
187        self.capture(ts);
188        ts
189    }
190
191    fn scan_jsx_identifier(&mut self, start: swc_common::BytePos) -> TokenAndSpan {
192        let ts = self.inner.scan_jsx_identifier(start);
193        self.capture(ts);
194        ts
195    }
196
197    fn scan_jsx_attribute_value(&mut self) -> TokenAndSpan {
198        let ts = self.inner.scan_jsx_attribute_value();
199        self.capture(ts);
200        ts
201    }
202
203    fn rescan_template_token(
204        &mut self,
205        start: swc_common::BytePos,
206        start_with_back_tick: bool,
207    ) -> TokenAndSpan {
208        let ts = self
209            .inner
210            .rescan_template_token(start, start_with_back_tick);
211        self.capture(ts);
212        ts
213    }
214}