swc_ecma_parser/lexer/
capturing.rs1use 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 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 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}