fix(transformer): RegExp transform handle Term::Quantifier (#5501)

`Term::Quantifier` contains a nested `Term` so we need to recurse into that `Term` to check if it contains any unsupported syntax.
This commit is contained in:
overlookmotel 2024-09-06 11:51:35 +00:00
parent 0c43d0cf8d
commit d1ece197c4
7 changed files with 30 additions and 14 deletions

View file

@ -197,27 +197,33 @@ impl<'a> RegExp<'a> {
///
/// Based on parsed regular expression pattern.
fn has_unsupported_regular_expression_pattern(&self, pattern: &Pattern<'a>) -> bool {
let terms_contains_unsupported = |terms: &[Term]| {
terms.iter().any(|term| match term {
Term::CapturingGroup(_) => self.named_capture_groups,
Term::UnicodePropertyEscape(_) => self.unicode_property_escapes,
pattern.body.body.iter().any(|alternative| {
alternative.body.iter().any(|term| self.term_contains_unsupported(term))
})
}
fn term_contains_unsupported(&self, mut term: &Term) -> bool {
// Loop because `Term::Quantifier` contains a nested `Term`
loop {
match term {
Term::CapturingGroup(_) => return self.named_capture_groups,
Term::UnicodePropertyEscape(_) => return self.unicode_property_escapes,
Term::CharacterClass(character_class) => {
self.unicode_property_escapes
return self.unicode_property_escapes
&& character_class_has_unicode_property_escape(character_class)
}
Term::LookAroundAssertion(assertion) => {
self.look_behind_assertions
return self.look_behind_assertions
&& matches!(
assertion.kind,
LookAroundAssertionKind::Lookbehind
| LookAroundAssertionKind::NegativeLookbehind
)
}
_ => false,
})
};
pattern.body.body.iter().any(|alternative| terms_contains_unsupported(&alternative.body))
Term::Quantifier(quantifier) => term = &quantifier.body,
_ => return false,
}
}
}
}

View file

@ -9,8 +9,11 @@ a1 = /a.b/s
// RegExpLookbehindAssertions
b1 = /(?<!x)/
b2 = /(?<=x)/
b3 = /((?<!x)){2}/
b4 = /((?<=x)){3}/
// RegExpNamedCaptureGroups
c1 = /(?<a>b)/
c2 = /((?<c>d)){4}/;
// RegExpUnicodePropertyEscapes
d1 = /\p{Emoji}/u
// ES2022

View file

@ -3,7 +3,10 @@ x2 = new RegExp(".", "u");
a1 = new RegExp("a.b", "s");
b1 = new RegExp("(?<!x)", "");
b2 = new RegExp("(?<=x)", "");
b3 = new RegExp("((?<!x)){2}", "");
b4 = new RegExp("((?<=x)){3}", "");
c1 = new RegExp("(?<a>b)", "");
c2 = new RegExp("((?<c>d)){4}", "");
d1 = new RegExp("\\p{Emoji}", "u");
f1 = new RegExp("y", "d");
g1 = new RegExp("[\\p{White_Space}&&\\p{ASCII}]", "v");

View file

@ -1 +1,2 @@
c1 = new RegExp("(?<a>b)", "");
c1 = new RegExp("(?<a>b)", "");
c2 = new RegExp("((?<a>b)){2}", "");

View file

@ -1 +1,2 @@
d1 = /\p{Emoji}/u
d1 = /\p{Emoji}/u
d2 = /\p{Emoji}{2}/u

View file

@ -1 +1,2 @@
d1 = new RegExp("\\p{Emoji}", "u");
d1 = new RegExp("\\p{Emoji}", "u");
d2 = new RegExp("\\p{Emoji}{2}", "u");