surql_parser/upstream/syn/lexer/compound/
js.rs1use super::Lexer;
2use crate::upstream::syn::error::{MessageKind, SyntaxError};
3use crate::upstream::syn::lexer::unicode::chars::JS_LINE_TERIMATORS;
4use crate::upstream::syn::token::{Token, t};
5pub fn javascript(lexer: &mut Lexer, start: Token) -> Result<(), SyntaxError> {
6 assert_eq!(
7 start.kind,
8 t!("{"),
9 "Invalid start of JavaScript compound token"
10 );
11 lex_js_function_body_inner(lexer)?;
12 Ok(())
13}
14fn lex_js_function_body_inner(lexer: &mut Lexer) -> Result<(), SyntaxError> {
16 let mut block_depth = 1;
17 loop {
18 let Some(byte) = lexer.reader.next() else {
19 let span = lexer.advance_span();
20 return Err(SyntaxError::new(format_args!(
21 "Invalid JavaScript function, encountered unexpected eof"
22 ))
23 .with_span(span, MessageKind::Error));
24 };
25 match byte {
26 b'`' => lex_js_string(lexer, b'`')?,
27 b'\'' => lex_js_string(lexer, b'\'')?,
28 b'\"' => lex_js_string(lexer, b'\"')?,
29 b'/' => match lexer.reader.peek() {
30 Some(b'/') => {
31 lexer.reader.next();
32 lex_js_single_comment(lexer)?;
33 }
34 Some(b'*') => {
35 lexer.reader.next();
36 lex_js_multi_comment(lexer)?
37 }
38 _ => {}
39 },
40 b'{' => {
41 block_depth += 1;
42 }
43 b'}' => {
44 block_depth -= 1;
45 if block_depth == 0 {
46 break;
47 }
48 }
49 x if !x.is_ascii() => {
50 lexer.reader.complete_char(x)?;
51 }
52 _ => {}
53 }
54 }
55 Ok(())
56}
57fn lex_js_string(lexer: &mut Lexer, enclosing_byte: u8) -> Result<(), SyntaxError> {
59 loop {
60 let Some(byte) = lexer.reader.next() else {
61 let span = lexer.advance_span();
62 return Err(SyntaxError::new(format_args!(
63 "Invalid JavaScript function, encountered unexpected eof"
64 ))
65 .with_span(span, MessageKind::Error));
66 };
67 if byte == enclosing_byte {
68 return Ok(());
69 }
70 if byte == b'\\' {
71 lexer.reader.next();
72 }
73 lexer.reader.convert_to_char(byte)?;
74 }
75}
76fn lex_js_single_comment(lexer: &mut Lexer) -> Result<(), SyntaxError> {
78 loop {
79 let Some(byte) = lexer.reader.next() else {
80 return Ok(());
81 };
82 let char = lexer.reader.convert_to_char(byte)?;
83 if JS_LINE_TERIMATORS.contains(&char) {
84 return Ok(());
85 }
86 }
87}
88fn lex_js_multi_comment(lexer: &mut Lexer) -> Result<(), SyntaxError> {
90 loop {
91 let Some(byte) = lexer.reader.next() else {
92 let span = lexer.advance_span();
93 return Err(SyntaxError::new(format_args!(
94 "Invalid JavaScript function, encountered unexpected eof"
95 ))
96 .with_span(span, MessageKind::Error));
97 };
98 if byte == b'*' && lexer.reader.peek() == Some(b'/') {
99 lexer.reader.next();
100 return Ok(());
101 }
102 lexer.reader.convert_to_char(byte)?;
103 }
104}