swc_ecma_regexp/
diagnostics.rs1use std::{
2 borrow::Cow,
3 fmt::{self, Display},
4};
5
6use swc_common::Span;
7
8type Either<T, E> = std::result::Result<T, E>;
9
10#[derive(Debug)]
11pub struct RegexpDiagnostic {
12 message: Cow<'static, str>,
13 label: Option<Either<Span, Vec<Span>>>,
14 help: Option<Cow<'static, str>>,
15}
16
17impl RegexpDiagnostic {
18 pub fn error<T: Into<Cow<'static, str>>>(message: T) -> Self {
19 RegexpDiagnostic {
20 message: message.into(),
21 label: None,
22 help: None,
23 }
24 }
25
26 pub fn with_label(mut self, span: Span) -> Self {
27 self.label = Some(Ok(span));
28 self
29 }
30
31 pub fn with_labels(mut self, spans: Vec<Span>) -> Self {
32 self.label = Some(Err(spans));
33 self
34 }
35
36 pub fn with_help<T: Into<Cow<'static, str>>>(mut self, help: T) -> Self {
37 self.help = Some(help.into());
38 self
39 }
40}
41
42impl Display for RegexpDiagnostic {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
44 self.message.fmt(f)
45 }
46}
47
48pub type Result<T> = std::result::Result<T, RegexpDiagnostic>;
49
50const PREFIX: &str = "Invalid regular expression:";
51
52#[cold]
53pub fn invalid_input(span: Span) -> RegexpDiagnostic {
54 RegexpDiagnostic::error(format!("{PREFIX} Invalid input string literal")).with_label(span)
55}
56
57#[cold]
60pub fn unknown_flag(span: Span, flag: &str) -> RegexpDiagnostic {
61 RegexpDiagnostic::error(format!("{PREFIX} Unknown flag: `{flag}` found")).with_label(span)
62}
63
64#[cold]
65pub fn duplicated_flags(span: Span, flag: &str) -> RegexpDiagnostic {
66 RegexpDiagnostic::error(format!("{PREFIX} Duplicated flag: `{flag}` found")).with_label(span)
67}
68
69#[cold]
70pub fn invalid_unicode_flags(span: Span) -> RegexpDiagnostic {
71 RegexpDiagnostic::error(format!(
72 "{PREFIX} Invalid unicode flags combination `u` and `v`"
73 ))
74 .with_label(span)
75}
76
77#[cold]
80pub fn duplicated_capturing_group_names(spans: Vec<Span>) -> RegexpDiagnostic {
81 RegexpDiagnostic::error(format!("{PREFIX} Duplicated capturing group names")).with_labels(spans)
82}
83
84#[cold]
85pub fn too_may_capturing_groups(span: Span) -> RegexpDiagnostic {
86 RegexpDiagnostic::error(format!("{PREFIX} Too many capturing groups")).with_label(span)
87}
88
89#[cold]
90pub fn parse_pattern_incomplete(span: Span) -> RegexpDiagnostic {
91 RegexpDiagnostic::error(format!("{PREFIX} Could not parse the entire pattern")).with_label(span)
92}
93
94#[cold]
95pub fn lone_quantifier(span: Span, kind: &str) -> RegexpDiagnostic {
96 RegexpDiagnostic::error(format!(
97 "{PREFIX} Lone quantifier found, expected with `{kind}`"
98 ))
99 .with_label(span)
100}
101
102#[cold]
103pub fn unterminated_pattern(span: Span, kind: &str) -> RegexpDiagnostic {
104 RegexpDiagnostic::error(format!("{PREFIX} Unterminated {kind}")).with_label(span)
105}
106
107#[cold]
108pub fn invalid_extended_atom_escape(span: Span) -> RegexpDiagnostic {
109 RegexpDiagnostic::error(format!("{PREFIX} Invalid extended atom escape")).with_label(span)
110}
111
112#[cold]
113pub fn invalid_braced_quantifier(span: Span) -> RegexpDiagnostic {
114 RegexpDiagnostic::error(format!("{PREFIX} Invalid braced quantifier")).with_label(span)
115}
116
117#[cold]
118pub fn invalid_indexed_reference(span: Span) -> RegexpDiagnostic {
119 RegexpDiagnostic::error(format!("{PREFIX} Invalid indexed reference")).with_label(span)
120}
121
122#[cold]
123pub fn empty_group_specifier(span: Span) -> RegexpDiagnostic {
124 RegexpDiagnostic::error(format!("{PREFIX} Group specifier is empty")).with_label(span)
125}
126
127#[cold]
128pub fn invalid_named_reference(span: Span) -> RegexpDiagnostic {
129 RegexpDiagnostic::error(format!("{PREFIX} Invalid named reference")).with_label(span)
130}
131
132#[cold]
133pub fn invalid_unicode_property_name_negative_strings(span: Span, name: &str) -> RegexpDiagnostic {
134 RegexpDiagnostic::error(format!(
135 "{PREFIX} Invalid property name `{name}`(negative + property of strings)"
136 ))
137 .with_label(span)
138}
139
140#[cold]
141pub fn invalid_character_class(span: Span) -> RegexpDiagnostic {
142 RegexpDiagnostic::error(format!(
143 "{PREFIX} Invalid character class with strings unicode property"
144 ))
145 .with_label(span)
146}
147
148#[cold]
149pub fn character_class_range_out_of_order(span: Span, kind: &str) -> RegexpDiagnostic {
150 RegexpDiagnostic::error(format!("{PREFIX} Character {kind} range out of order"))
151 .with_label(span)
152}
153
154#[cold]
155pub fn character_class_range_invalid_atom(span: Span) -> RegexpDiagnostic {
156 RegexpDiagnostic::error(format!("{PREFIX} Character class range with invalid atom"))
157 .with_label(span)
158}
159
160#[cold]
161pub fn invalid_class_atom(span: Span) -> RegexpDiagnostic {
162 RegexpDiagnostic::error(format!("{PREFIX} Invalid class atom")).with_label(span)
163}
164
165#[cold]
166pub fn empty_class_set_expression(span: Span) -> RegexpDiagnostic {
167 RegexpDiagnostic::error(format!("{PREFIX} Expected nonempty class set expression"))
168 .with_label(span)
169}
170
171#[cold]
172pub fn class_intersection_unexpected_ampersand(span: Span) -> RegexpDiagnostic {
173 RegexpDiagnostic::error(format!(
174 "{PREFIX} Unexpected `&` inside of class intersection"
175 ))
176 .with_label(span)
177}
178
179#[cold]
180pub fn class_set_expression_invalid_character(span: Span, kind: &str) -> RegexpDiagnostic {
181 RegexpDiagnostic::error(format!("{PREFIX} Unexpected character inside of {kind}"))
182 .with_label(span)
183}
184
185#[cold]
186pub fn character_class_contents_invalid_operands(span: Span) -> RegexpDiagnostic {
187 RegexpDiagnostic::error(format!(
188 "{PREFIX} Invalid class operands inside of character class contents"
189 ))
190 .with_label(span)
191}
192
193#[cold]
194pub fn too_large_number_in_braced_quantifier(span: Span) -> RegexpDiagnostic {
195 RegexpDiagnostic::error(format!("{PREFIX} Number is too large in braced quantifier"))
196 .with_label(span)
197}
198
199#[cold]
200pub fn braced_quantifier_out_of_order(span: Span) -> RegexpDiagnostic {
201 RegexpDiagnostic::error(format!(
202 "{PREFIX} Numbers out of order in braced quantifier"
203 ))
204 .with_label(span)
205}
206
207#[cold]
208pub fn too_large_number_digits(span: Span, kind: &str) -> RegexpDiagnostic {
209 RegexpDiagnostic::error(format!("{PREFIX} Number is too large in {kind} digits"))
210 .with_label(span)
211}
212
213#[cold]
214pub fn invalid_unicode_property(span: Span, kind: &str) -> RegexpDiagnostic {
215 RegexpDiagnostic::error(format!("{PREFIX} Invalid unicode property {kind}")).with_label(span)
216}
217
218#[cold]
219pub fn invalid_unicode_property_of_strings(span: Span, name: &str) -> RegexpDiagnostic {
220 RegexpDiagnostic::error(format!("{PREFIX} Invalid unicode property `{name}`"))
221 .with_help("Enable `UnicodeSetsMode` to use this property")
222 .with_label(span)
223}
224
225#[cold]
226pub fn invalid_unicode_escape_sequence(span: Span) -> RegexpDiagnostic {
227 RegexpDiagnostic::error(format!("{PREFIX} Invalid unicode escape sequence")).with_label(span)
228}
229
230#[cold]
231pub fn invalid_surrogate_pair(span: Span) -> RegexpDiagnostic {
232 RegexpDiagnostic::error(format!("{PREFIX} Invalid surrogate pair")).with_label(span)
233}
234
235#[cold]
236pub fn invalid_modifiers(span: Span) -> RegexpDiagnostic {
237 RegexpDiagnostic::error(format!("{PREFIX} Invalid modifiers")).with_label(span)
238}
239
240#[cold]
241pub fn unknown_modifiers(span: Span) -> RegexpDiagnostic {
242 RegexpDiagnostic::error(format!("{PREFIX} Unknown modifiers")).with_label(span)
243}