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