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
45impl<I: Iterator<Item = TokenAndSpan>> Iterator for Capturing<I> {
46 type Item = TokenAndSpan;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 let next = self.inner.next();
50
51 match next {
52 Some(ts) => {
53 let v = &mut self.captured;
54
55 while let Some(last) = v.last() {
57 if last.span.lo >= ts.span.lo {
58 v.pop();
59 } else {
60 break;
61 }
62 }
63
64 v.push(ts);
65
66 Some(ts)
67 }
68 None => None,
69 }
70 }
71}
72
73impl<I: swc_ecma_lexer::common::input::Tokens<TokenAndSpan>>
74 swc_ecma_lexer::common::input::Tokens<TokenAndSpan> for Capturing<I>
75{
76 type Checkpoint = CapturingCheckpoint<I>;
77
78 fn checkpoint_save(&self) -> Self::Checkpoint {
79 Self::Checkpoint {
80 pos: self.captured.len(),
81 inner: self.inner.checkpoint_save(),
82 }
83 }
84
85 fn checkpoint_load(&mut self, checkpoint: Self::Checkpoint) {
86 self.captured.truncate(checkpoint.pos);
87 self.inner.checkpoint_load(checkpoint.inner);
88 }
89
90 fn set_ctx(&mut self, ctx: swc_ecma_lexer::common::context::Context) {
91 self.inner.set_ctx(ctx);
92 }
93
94 fn ctx(&self) -> swc_ecma_lexer::common::context::Context {
95 self.inner.ctx()
96 }
97
98 fn ctx_mut(&mut self) -> &mut swc_ecma_lexer::common::context::Context {
99 self.inner.ctx_mut()
100 }
101
102 fn syntax(&self) -> SyntaxFlags {
103 self.inner.syntax()
104 }
105
106 fn target(&self) -> swc_ecma_ast::EsVersion {
107 self.inner.target()
108 }
109
110 fn set_expr_allowed(&mut self, allow: bool) {
111 self.inner.set_expr_allowed(allow);
112 }
113
114 fn set_next_regexp(&mut self, start: Option<swc_common::BytePos>) {
115 self.inner.set_next_regexp(start);
116 }
117
118 fn token_context(&self) -> &swc_ecma_lexer::lexer::TokenContexts {
119 self.inner.token_context()
120 }
121
122 fn token_context_mut(&mut self) -> &mut swc_ecma_lexer::lexer::TokenContexts {
123 self.inner.token_context_mut()
124 }
125
126 fn set_token_context(&mut self, c: swc_ecma_lexer::lexer::TokenContexts) {
127 self.inner.set_token_context(c);
128 }
129
130 fn add_error(&mut self, error: swc_ecma_lexer::error::Error) {
131 self.inner.add_error(error);
132 }
133
134 fn add_module_mode_error(&mut self, error: swc_ecma_lexer::error::Error) {
135 self.inner.add_module_mode_error(error);
136 }
137
138 fn end_pos(&self) -> swc_common::BytePos {
139 self.inner.end_pos()
140 }
141
142 fn take_errors(&mut self) -> Vec<swc_ecma_lexer::error::Error> {
143 self.inner.take_errors()
144 }
145
146 fn take_script_module_errors(&mut self) -> Vec<swc_ecma_lexer::error::Error> {
147 self.inner.take_script_module_errors()
148 }
149
150 fn update_token_flags(&mut self, f: impl FnOnce(&mut swc_ecma_lexer::lexer::TokenFlags)) {
151 self.inner.update_token_flags(f);
152 }
153
154 fn token_flags(&self) -> swc_ecma_lexer::lexer::TokenFlags {
155 self.inner.token_flags()
156 }
157}
158
159impl<I: Tokens> Tokens for Capturing<I> {
160 fn clone_token_value(&self) -> Option<super::TokenValue> {
161 self.inner.clone_token_value()
162 }
163
164 fn take_token_value(&mut self) -> Option<super::TokenValue> {
165 self.inner.take_token_value()
166 }
167
168 fn get_token_value(&self) -> Option<&super::TokenValue> {
169 self.inner.get_token_value()
170 }
171
172 fn set_token_value(&mut self, token_value: Option<super::TokenValue>) {
173 self.inner.set_token_value(token_value);
174 }
175
176 fn scan_jsx_token(&mut self, allow_multiline_jsx_text: bool) -> TokenAndSpan {
177 self.inner.scan_jsx_token(allow_multiline_jsx_text)
178 }
179
180 fn scan_jsx_open_el_terminal_token(&mut self) -> TokenAndSpan {
181 self.inner.scan_jsx_open_el_terminal_token()
182 }
183
184 fn rescan_jsx_open_el_terminal_token(&mut self, reset: swc_common::BytePos) -> TokenAndSpan {
185 self.inner.rescan_jsx_open_el_terminal_token(reset)
186 }
187
188 fn rescan_jsx_token(
189 &mut self,
190 allow_multiline_jsx_text: bool,
191 reset: swc_common::BytePos,
192 ) -> TokenAndSpan {
193 self.inner.rescan_jsx_token(allow_multiline_jsx_text, reset)
194 }
195
196 fn scan_jsx_identifier(&mut self, start: swc_common::BytePos) -> TokenAndSpan {
197 self.inner.scan_jsx_identifier(start)
198 }
199
200 fn scan_jsx_attribute_value(&mut self) -> TokenAndSpan {
201 self.inner.scan_jsx_attribute_value()
202 }
203
204 fn rescan_template_token(
205 &mut self,
206 start: swc_common::BytePos,
207 start_with_back_tick: bool,
208 ) -> TokenAndSpan {
209 self.inner
210 .rescan_template_token(start, start_with_back_tick)
211 }
212}