Skip to main content

boa_ast/expression/
regexp.rs

1//! This module contains the ECMAScript representation regular expressions.
2//!
3//! More information:
4//!  - [ECMAScript reference][spec]
5//!  - [MDN documentation][mdn]
6//!
7//! [spec]: https://tc39.es/ecma262/#sec-literals-regular-expression-literals
8//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
9
10use std::ops::ControlFlow;
11
12use boa_interner::{Interner, Sym, ToInternedString};
13
14use crate::{
15    Span, Spanned,
16    visitor::{VisitWith, Visitor, VisitorMut},
17};
18
19use super::Expression;
20
21/// Regular expressions in ECMAScript.
22///
23/// More information:
24///  - [ECMAScript reference][spec]
25///  - [MDN documentation][mdn]
26///
27/// [spec]: https://tc39.es/ecma262/#sec-literals-regular-expression-literals
28/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct RegExpLiteral {
33    pattern: Sym,
34    flags: Sym,
35    span: Span,
36}
37
38impl RegExpLiteral {
39    /// Create a new [`RegExpLiteral`].
40    #[inline]
41    #[must_use]
42    pub const fn new(pattern: Sym, flags: Sym, span: Span) -> Self {
43        Self {
44            pattern,
45            flags,
46            span,
47        }
48    }
49
50    /// Get the pattern part of the [`RegExpLiteral`].
51    #[inline]
52    #[must_use]
53    pub const fn pattern(&self) -> Sym {
54        self.pattern
55    }
56
57    /// Get the flags part of the [`RegExpLiteral`].
58    #[inline]
59    #[must_use]
60    pub const fn flags(&self) -> Sym {
61        self.flags
62    }
63}
64
65impl Spanned for RegExpLiteral {
66    #[inline]
67    fn span(&self) -> Span {
68        self.span
69    }
70}
71
72impl ToInternedString for RegExpLiteral {
73    #[inline]
74    fn to_interned_string(&self, interner: &Interner) -> String {
75        let pattern = interner.resolve_expect(self.pattern);
76        let flags = interner.resolve_expect(self.flags);
77        format!("/{pattern}/{flags}")
78    }
79}
80
81impl From<RegExpLiteral> for Expression {
82    #[inline]
83    fn from(value: RegExpLiteral) -> Self {
84        Self::RegExpLiteral(value)
85    }
86}
87
88impl VisitWith for RegExpLiteral {
89    #[inline]
90    fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
91    where
92        V: Visitor<'a>,
93    {
94        visitor.visit_sym(&self.pattern)?;
95        visitor.visit_sym(&self.flags)
96    }
97
98    #[inline]
99    fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
100    where
101        V: VisitorMut<'a>,
102    {
103        visitor.visit_sym_mut(&mut self.pattern)?;
104        visitor.visit_sym_mut(&mut self.flags)
105    }
106}