Skip to main content

boa_ast/
source_text.rs

1use crate::{LinearPosition, LinearSpan};
2
3/// Source text.
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[derive(Clone, Debug)]
6pub struct SourceText {
7    source_text: Vec<u16>,
8}
9
10impl SourceText {
11    /// Constructs a new, empty `SourceText` with at least the specified capacity.
12    #[must_use]
13    pub fn with_capacity(capacity: usize) -> Self {
14        Self {
15            source_text: Vec::with_capacity(capacity),
16        }
17    }
18
19    /// Get current `LinearPosition`.
20    #[must_use]
21    pub fn cur_linear_position(&self) -> LinearPosition {
22        LinearPosition::new(self.source_text.len())
23    }
24
25    /// Get code points from `pos` to the current end.
26    #[must_use]
27    pub fn get_code_points_from_pos(&self, pos: LinearPosition) -> &[u16] {
28        &self.source_text[pos.pos()..]
29    }
30
31    /// Get code points within `span`.
32    #[must_use]
33    pub fn get_code_points_from_span(&self, span: LinearSpan) -> &[u16] {
34        &self.source_text[span.start().pos()..span.end().pos()]
35    }
36
37    /// Remove last code point.
38    #[inline]
39    pub fn remove_last_code_point(&mut self) {
40        self.source_text.pop();
41    }
42
43    /// Collect code point.
44    ///
45    /// # Panics
46    ///
47    /// On invalid code point.
48    #[inline]
49    pub fn collect_code_point(&mut self, cp: u32) {
50        if let Ok(cu) = cp.try_into() {
51            self.push(cu);
52            return;
53        }
54        let cp = cp - 0x10000;
55        let cu1 = (cp / 0x400 + 0xD800)
56            .try_into()
57            .expect("Invalid code point");
58        let cu2 = (cp % 0x400 + 0xDC00)
59            .try_into()
60            .expect("Invalid code point");
61        self.push(cu1);
62        self.push(cu2);
63    }
64
65    #[inline]
66    fn push(&mut self, cp: u16) {
67        self.source_text.push(cp);
68    }
69}
70
71const DEFAULT_CAPACITY: usize = 4 * 1024;
72
73impl Default for SourceText {
74    fn default() -> Self {
75        Self::with_capacity(DEFAULT_CAPACITY)
76    }
77}