oxc/crates/oxc_regular_expression/src/diagnostics.rs
leaysgur f8e1907c4f feat(regular_expression): Intro ConstructorParser(and LiteralParser) to handle escape sequence in RegExp('pat') (#6635)
Preparation for #6141

`oxc_regular_expression` can already parse and validate both `/regexp-literal/` and `new RegExp("string-literal")`.

But one thing that is not well-supported was reporting `Span` for the `RegExp("string-literal-with-\\escape")` case.

For example, these two cases produce the same `RegExp` instances in JavaScript:

- `/\d+/`
- `new RegExp("\\d+")`

For now, mainly in `oxc_linter`, the latter case is parsed with `oxc_parser` -> `ast::literal::StringLiteral` AST node -> `value` property.

At this point, escape sequences are resolved(!), `oxc_regular_expression` can handle aligned `&str` as an argument without any problem in both cases.

However, in terms of `Span` representation, these cases should be handled differently because of the `\\` in string literals...

As a result, the parsed AST's `Span` for `new RegExp("string-literal")` is not accurate if it contains escape sequences.

e.g. a01a5dfdaf/crates/oxc_linter/src/snapshots/no_invalid_regexp.snap (L118-L122)

Each time the `\` appears, the subsequent position is shifted. `_` should be placed under `*` in this case.

So... to resolve this issue, we need to implement `string_literal_parser` first, and use them as reading units of `oxc_regular_expression`.
2024-10-21 07:07:27 +00:00

184 lines
5.8 KiB
Rust

use oxc_diagnostics::OxcDiagnostic;
use oxc_span::Span;
const PREFIX: &str = "Invalid regular expression:";
#[cold]
pub fn invalid_input(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid input string literal")).with_label(span)
}
// ---
#[cold]
pub fn unknown_flag(span: Span, flag: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Unknown flag: `{flag}` found")).with_label(span)
}
#[cold]
pub fn duplicated_flags(span: Span, flag: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Duplicated flag: `{flag}` found")).with_label(span)
}
#[cold]
pub fn invalid_unicode_flags(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid unicode flags combination `u` and `v`"))
.with_label(span)
}
// ---
#[cold]
pub fn duplicated_capturing_group_names(spans: Vec<Span>) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Duplicated capturing group names")).with_labels(spans)
}
#[cold]
pub fn too_may_capturing_groups(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Too many capturing groups")).with_label(span)
}
#[cold]
pub fn parse_pattern_incomplete(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Could not parse the entire pattern")).with_label(span)
}
#[cold]
pub fn lone_quantifier(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Lone quantifier found, expected with `{kind}`"))
.with_label(span)
}
#[cold]
pub fn unterminated_pattern(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Unterminated {kind}")).with_label(span)
}
#[cold]
pub fn invalid_extended_atom_escape(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid extended atom escape")).with_label(span)
}
#[cold]
pub fn invalid_braced_quantifier(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid braced quantifier")).with_label(span)
}
#[cold]
pub fn invalid_indexed_reference(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid indexed reference")).with_label(span)
}
#[cold]
pub fn empty_group_specifier(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Group specifier is empty")).with_label(span)
}
#[cold]
pub fn invalid_named_reference(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid named reference")).with_label(span)
}
#[cold]
pub fn invalid_unicode_property_name_negative_strings(span: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!(
"{PREFIX} Invalid property name `{name}`(negative + property of strings)"
))
.with_label(span)
}
#[cold]
pub fn invalid_character_class(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid character class with strings unicode property"))
.with_label(span)
}
#[cold]
pub fn character_class_range_out_of_order(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Character {kind} range out of order")).with_label(span)
}
#[cold]
pub fn character_class_range_invalid_atom(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Character class range with invalid atom"))
.with_label(span)
}
#[cold]
pub fn invalid_class_atom(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid class atom")).with_label(span)
}
#[cold]
pub fn empty_class_set_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Expected nonempty class set expression"))
.with_label(span)
}
#[cold]
pub fn class_intersection_unexpected_ampersand(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Unexpected `&` inside of class intersection"))
.with_label(span)
}
#[cold]
pub fn class_set_expression_invalid_character(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Unexpected character inside of {kind}")).with_label(span)
}
#[cold]
pub fn character_class_contents_invalid_operands(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!(
"{PREFIX} Invalid class operands inside of character class contents"
))
.with_label(span)
}
#[cold]
pub fn too_large_number_in_braced_quantifier(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Number is too large in braced quantifier"))
.with_label(span)
}
#[cold]
pub fn braced_quantifier_out_of_order(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Numbers out of order in braced quantifier"))
.with_label(span)
}
#[cold]
pub fn too_large_number_digits(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Number is too large in {kind} digits")).with_label(span)
}
#[cold]
pub fn invalid_unicode_property(span: Span, kind: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid unicode property {kind}")).with_label(span)
}
#[cold]
pub fn invalid_unicode_property_of_strings(span: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid unicode property `{name}`"))
.with_help("Enable `UnicodeSetsMode` to use this property")
.with_label(span)
}
#[cold]
pub fn invalid_unicode_escape_sequence(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid unicode escape sequence")).with_label(span)
}
#[cold]
pub fn invalid_surrogate_pair(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid surrogate pair")).with_label(span)
}
#[cold]
pub fn invalid_modifiers(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Invalid modifiers")).with_label(span)
}
#[cold]
pub fn unknown_modifiers(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!("{PREFIX} Unknown modifiers")).with_label(span)
}