swc_ecma_regexp/parser/
parser_impl.rs1use super::{
2 flags_parser::FlagsParser, pattern_parser::PatternParser, reader::Reader,
3 span_factory::SpanFactory,
4};
5use crate::{
6 ast,
7 diagnostics::{self, Result},
8 options::Options,
9};
10
11pub struct LiteralParser<'a> {
15 pattern_text: &'a str,
16 flags_text: Option<&'a str>,
17 options: Options,
18}
19
20impl<'a> LiteralParser<'a> {
21 pub fn new(pattern_text: &'a str, flags_text: Option<&'a str>, options: Options) -> Self {
22 Self {
23 pattern_text,
24 flags_text,
25 options,
26 }
27 }
28
29 pub fn parse(self) -> Result<ast::Pattern> {
30 let parse_string_literal = false;
31 let Options {
32 pattern_span_offset,
33 flags_span_offset,
34 } = self.options;
35
36 let (unicode_mode, unicode_sets_mode) = if let Some(flags_text) = self.flags_text {
37 let reader = Reader::initialize(flags_text, true, parse_string_literal)?; FlagsParser::new(reader, flags_span_offset).parse()?
40 } else {
41 (false, false)
42 };
43
44 let pattern_text = if self.pattern_text.is_empty() {
45 "(?:)"
46 } else {
47 self.pattern_text
48 };
49 let reader = Reader::initialize(pattern_text, unicode_mode, parse_string_literal)?; PatternParser::new(
52 reader,
53 (unicode_mode, unicode_sets_mode),
54 pattern_span_offset,
55 )
56 .parse()
57 }
58}
59
60pub struct ConstructorParser<'a> {
69 pattern_text: &'a str,
70 flags_text: Option<&'a str>,
71 options: Options,
72}
73
74impl<'a> ConstructorParser<'a> {
75 pub fn new(pattern_text: &'a str, flags_text: Option<&'a str>, options: Options) -> Self {
76 Self {
77 pattern_text,
78 flags_text,
79 options,
80 }
81 }
82
83 pub fn parse(self) -> Result<ast::Pattern> {
84 let parse_string_literal = true;
85 let Options {
86 pattern_span_offset,
87 flags_span_offset,
88 } = self.options;
89
90 let (unicode_mode, unicode_sets_mode) = if let Some(flags_text) = self.flags_text {
91 let reader =
92 Reader::initialize(flags_text, true, parse_string_literal).map_err(|_| {
93 let span_start = flags_span_offset;
94 #[expect(clippy::cast_possible_truncation)]
95 let span_end = flags_span_offset + flags_text.len() as u32;
96 diagnostics::invalid_input(SpanFactory::span_from_u32(span_start, span_end))
97 })?;
98
99 FlagsParser::new(reader, self.options.flags_span_offset).parse()?
100 } else {
101 (false, false)
102 };
103
104 let pattern_text = if matches!(self.pattern_text, r#""""# | "''") {
105 r#""(?:)""#
106 } else {
107 self.pattern_text
108 };
109 let reader =
110 Reader::initialize(pattern_text, unicode_mode, parse_string_literal).map_err(|_| {
111 let span_start = pattern_span_offset;
112 #[expect(clippy::cast_possible_truncation)]
113 let span_end = pattern_span_offset + pattern_text.len() as u32;
114 diagnostics::invalid_input(SpanFactory::span_from_u32(span_start, span_end))
115 })?;
116
117 PatternParser::new(
118 reader,
119 (unicode_mode, unicode_sets_mode),
120 pattern_span_offset,
121 )
122 .parse()
123 }
124}