boa/syntax/lexer/
spread.rs

1//! This module implements lexing for spread (...) literals used in the JavaScript programing language.
2
3use super::{Cursor, Error, Tokenizer};
4use crate::{
5    profiler::BoaProfiler,
6    syntax::{
7        ast::{Position, Punctuator, Span},
8        lexer::Token,
9    },
10};
11use std::io::Read;
12
13/// Spread literal lexing.
14///
15/// Note: expects for the initializer `'` or `"` to already be consumed from the cursor.
16///
17/// More information:
18///  - [ECMAScript reference][spec]
19///  - [MDN documentation][mdn]
20///
21/// [spec]: https://tc39.es/ecma262/#prod-SpreadElement
22/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
23#[derive(Debug, Clone, Copy)]
24pub(super) struct SpreadLiteral;
25
26impl SpreadLiteral {
27    /// Creates a new string literal lexer.
28    pub(super) fn new() -> Self {
29        Self {}
30    }
31}
32
33impl<R> Tokenizer<R> for SpreadLiteral {
34    fn lex(&mut self, cursor: &mut Cursor<R>, start_pos: Position) -> Result<Token, Error>
35    where
36        R: Read,
37    {
38        let _timer = BoaProfiler::global().start_event("SpreadLiteral", "Lexing");
39
40        // . or ...
41        if cursor.next_is(b'.')? {
42            if cursor.next_is(b'.')? {
43                Ok(Token::new(
44                    Punctuator::Spread.into(),
45                    Span::new(start_pos, cursor.pos()),
46                ))
47            } else {
48                Err(Error::syntax(
49                    "Expecting Token '.' as part of spread",
50                    cursor.pos(),
51                ))
52            }
53        } else {
54            Ok(Token::new(
55                Punctuator::Dot.into(),
56                Span::new(start_pos, cursor.pos()),
57            ))
58        }
59    }
60}