@eslint-community/regexpp 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/index.d.ts +252 -12
- package/index.js +718 -123
- package/index.js.map +1 -1
- package/index.mjs +718 -123
- package/index.mjs.map +1 -1
- package/package.json +6 -1
package/index.js
CHANGED
|
@@ -6,6 +6,8 @@ var ast = /*#__PURE__*/Object.freeze({
|
|
|
6
6
|
__proto__: null
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
+
const latestEcmaVersion = 2024;
|
|
10
|
+
|
|
9
11
|
let largeIdStartRanges = undefined;
|
|
10
12
|
let largeIdContinueRanges = undefined;
|
|
11
13
|
function isIdStart(cp) {
|
|
@@ -72,13 +74,14 @@ function restoreRanges(data) {
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
class DataSet {
|
|
75
|
-
constructor(raw2018, raw2019, raw2020, raw2021, raw2022, raw2023) {
|
|
77
|
+
constructor(raw2018, raw2019, raw2020, raw2021, raw2022, raw2023, raw2024) {
|
|
76
78
|
this._raw2018 = raw2018;
|
|
77
79
|
this._raw2019 = raw2019;
|
|
78
80
|
this._raw2020 = raw2020;
|
|
79
81
|
this._raw2021 = raw2021;
|
|
80
82
|
this._raw2022 = raw2022;
|
|
81
83
|
this._raw2023 = raw2023;
|
|
84
|
+
this._raw2024 = raw2024;
|
|
82
85
|
}
|
|
83
86
|
get es2018() {
|
|
84
87
|
var _a;
|
|
@@ -104,12 +107,16 @@ class DataSet {
|
|
|
104
107
|
var _a;
|
|
105
108
|
return ((_a = this._set2023) !== null && _a !== void 0 ? _a : (this._set2023 = new Set(this._raw2023.split(" "))));
|
|
106
109
|
}
|
|
110
|
+
get es2024() {
|
|
111
|
+
var _a;
|
|
112
|
+
return ((_a = this._set2024) !== null && _a !== void 0 ? _a : (this._set2024 = new Set(this._raw2024.split(" "))));
|
|
113
|
+
}
|
|
107
114
|
}
|
|
108
115
|
const gcNameSet = new Set(["General_Category", "gc"]);
|
|
109
116
|
const scNameSet = new Set(["Script", "Script_Extensions", "sc", "scx"]);
|
|
110
|
-
const gcValueSets = new DataSet("C Cased_Letter Cc Cf Close_Punctuation Cn Co Combining_Mark Connector_Punctuation Control Cs Currency_Symbol Dash_Punctuation Decimal_Number Enclosing_Mark Final_Punctuation Format Initial_Punctuation L LC Letter Letter_Number Line_Separator Ll Lm Lo Lowercase_Letter Lt Lu M Mark Math_Symbol Mc Me Mn Modifier_Letter Modifier_Symbol N Nd Nl No Nonspacing_Mark Number Open_Punctuation Other Other_Letter Other_Number Other_Punctuation Other_Symbol P Paragraph_Separator Pc Pd Pe Pf Pi Po Private_Use Ps Punctuation S Sc Separator Sk Sm So Space_Separator Spacing_Mark Surrogate Symbol Titlecase_Letter Unassigned Uppercase_Letter Z Zl Zp Zs cntrl digit punct", "", "", "", "", "");
|
|
111
|
-
const scValueSets = new DataSet("Adlam Adlm Aghb Ahom Anatolian_Hieroglyphs Arab Arabic Armenian Armi Armn Avestan Avst Bali Balinese Bamu Bamum Bass Bassa_Vah Batak Batk Beng Bengali Bhaiksuki Bhks Bopo Bopomofo Brah Brahmi Brai Braille Bugi Buginese Buhd Buhid Cakm Canadian_Aboriginal Cans Cari Carian Caucasian_Albanian Chakma Cham Cher Cherokee Common Copt Coptic Cprt Cuneiform Cypriot Cyrillic Cyrl Deseret Deva Devanagari Dsrt Dupl Duployan Egyp Egyptian_Hieroglyphs Elba Elbasan Ethi Ethiopic Geor Georgian Glag Glagolitic Gonm Goth Gothic Gran Grantha Greek Grek Gujarati Gujr Gurmukhi Guru Han Hang Hangul Hani Hano Hanunoo Hatr Hatran Hebr Hebrew Hira Hiragana Hluw Hmng Hung Imperial_Aramaic Inherited Inscriptional_Pahlavi Inscriptional_Parthian Ital Java Javanese Kaithi Kali Kana Kannada Katakana Kayah_Li Khar Kharoshthi Khmer Khmr Khoj Khojki Khudawadi Knda Kthi Lana Lao Laoo Latin Latn Lepc Lepcha Limb Limbu Lina Linb Linear_A Linear_B Lisu Lyci Lycian Lydi Lydian Mahajani Mahj Malayalam Mand Mandaic Mani Manichaean Marc Marchen Masaram_Gondi Meetei_Mayek Mend Mende_Kikakui Merc Mero Meroitic_Cursive Meroitic_Hieroglyphs Miao Mlym Modi Mong Mongolian Mro Mroo Mtei Mult Multani Myanmar Mymr Nabataean Narb Nbat New_Tai_Lue Newa Nko Nkoo Nshu Nushu Ogam Ogham Ol_Chiki Olck Old_Hungarian Old_Italic Old_North_Arabian Old_Permic Old_Persian Old_South_Arabian Old_Turkic Oriya Orkh Orya Osage Osge Osma Osmanya Pahawh_Hmong Palm Palmyrene Pau_Cin_Hau Pauc Perm Phag Phags_Pa Phli Phlp Phnx Phoenician Plrd Prti Psalter_Pahlavi Qaac Qaai Rejang Rjng Runic Runr Samaritan Samr Sarb Saur Saurashtra Sgnw Sharada Shavian Shaw Shrd Sidd Siddham SignWriting Sind Sinh Sinhala Sora Sora_Sompeng Soyo Soyombo Sund Sundanese Sylo Syloti_Nagri Syrc Syriac Tagalog Tagb Tagbanwa Tai_Le Tai_Tham Tai_Viet Takr Takri Tale Talu Tamil Taml Tang Tangut Tavt Telu Telugu Tfng Tglg Thaa Thaana Thai Tibetan Tibt Tifinagh Tirh Tirhuta Ugar Ugaritic Vai Vaii Wara Warang_Citi Xpeo Xsux Yi Yiii Zanabazar_Square Zanb Zinh Zyyy", "Dogr Dogra Gong Gunjala_Gondi Hanifi_Rohingya Maka Makasar Medefaidrin Medf Old_Sogdian Rohg Sogd Sogdian Sogo", "Elym Elymaic Hmnp Nand Nandinagari Nyiakeng_Puachue_Hmong Wancho Wcho", "Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi", "Cpmn Cypro_Minoan Old_Uyghur Ougr Tangsa Tnsa Toto Vith Vithkuqi", "Hrkt Katakana_Or_Hiragana Kawi Nag_Mundari Nagm Unknown Zzzz");
|
|
112
|
-
const binPropertySets = new DataSet("AHex ASCII ASCII_Hex_Digit Alpha Alphabetic Any Assigned Bidi_C Bidi_Control Bidi_M Bidi_Mirrored CI CWCF CWCM CWKCF CWL CWT CWU Case_Ignorable Cased Changes_When_Casefolded Changes_When_Casemapped Changes_When_Lowercased Changes_When_NFKC_Casefolded Changes_When_Titlecased Changes_When_Uppercased DI Dash Default_Ignorable_Code_Point Dep Deprecated Dia Diacritic Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Ext Extender Gr_Base Gr_Ext Grapheme_Base Grapheme_Extend Hex Hex_Digit IDC IDS IDSB IDST IDS_Binary_Operator IDS_Trinary_Operator ID_Continue ID_Start Ideo Ideographic Join_C Join_Control LOE Logical_Order_Exception Lower Lowercase Math NChar Noncharacter_Code_Point Pat_Syn Pat_WS Pattern_Syntax Pattern_White_Space QMark Quotation_Mark RI Radical Regional_Indicator SD STerm Sentence_Terminal Soft_Dotted Term Terminal_Punctuation UIdeo Unified_Ideograph Upper Uppercase VS Variation_Selector White_Space XIDC XIDS XID_Continue XID_Start space", "Extended_Pictographic", "", "EBase EComp EMod EPres ExtPict", "", "");
|
|
117
|
+
const gcValueSets = new DataSet("C Cased_Letter Cc Cf Close_Punctuation Cn Co Combining_Mark Connector_Punctuation Control Cs Currency_Symbol Dash_Punctuation Decimal_Number Enclosing_Mark Final_Punctuation Format Initial_Punctuation L LC Letter Letter_Number Line_Separator Ll Lm Lo Lowercase_Letter Lt Lu M Mark Math_Symbol Mc Me Mn Modifier_Letter Modifier_Symbol N Nd Nl No Nonspacing_Mark Number Open_Punctuation Other Other_Letter Other_Number Other_Punctuation Other_Symbol P Paragraph_Separator Pc Pd Pe Pf Pi Po Private_Use Ps Punctuation S Sc Separator Sk Sm So Space_Separator Spacing_Mark Surrogate Symbol Titlecase_Letter Unassigned Uppercase_Letter Z Zl Zp Zs cntrl digit punct", "", "", "", "", "", "");
|
|
118
|
+
const scValueSets = new DataSet("Adlam Adlm Aghb Ahom Anatolian_Hieroglyphs Arab Arabic Armenian Armi Armn Avestan Avst Bali Balinese Bamu Bamum Bass Bassa_Vah Batak Batk Beng Bengali Bhaiksuki Bhks Bopo Bopomofo Brah Brahmi Brai Braille Bugi Buginese Buhd Buhid Cakm Canadian_Aboriginal Cans Cari Carian Caucasian_Albanian Chakma Cham Cher Cherokee Common Copt Coptic Cprt Cuneiform Cypriot Cyrillic Cyrl Deseret Deva Devanagari Dsrt Dupl Duployan Egyp Egyptian_Hieroglyphs Elba Elbasan Ethi Ethiopic Geor Georgian Glag Glagolitic Gonm Goth Gothic Gran Grantha Greek Grek Gujarati Gujr Gurmukhi Guru Han Hang Hangul Hani Hano Hanunoo Hatr Hatran Hebr Hebrew Hira Hiragana Hluw Hmng Hung Imperial_Aramaic Inherited Inscriptional_Pahlavi Inscriptional_Parthian Ital Java Javanese Kaithi Kali Kana Kannada Katakana Kayah_Li Khar Kharoshthi Khmer Khmr Khoj Khojki Khudawadi Knda Kthi Lana Lao Laoo Latin Latn Lepc Lepcha Limb Limbu Lina Linb Linear_A Linear_B Lisu Lyci Lycian Lydi Lydian Mahajani Mahj Malayalam Mand Mandaic Mani Manichaean Marc Marchen Masaram_Gondi Meetei_Mayek Mend Mende_Kikakui Merc Mero Meroitic_Cursive Meroitic_Hieroglyphs Miao Mlym Modi Mong Mongolian Mro Mroo Mtei Mult Multani Myanmar Mymr Nabataean Narb Nbat New_Tai_Lue Newa Nko Nkoo Nshu Nushu Ogam Ogham Ol_Chiki Olck Old_Hungarian Old_Italic Old_North_Arabian Old_Permic Old_Persian Old_South_Arabian Old_Turkic Oriya Orkh Orya Osage Osge Osma Osmanya Pahawh_Hmong Palm Palmyrene Pau_Cin_Hau Pauc Perm Phag Phags_Pa Phli Phlp Phnx Phoenician Plrd Prti Psalter_Pahlavi Qaac Qaai Rejang Rjng Runic Runr Samaritan Samr Sarb Saur Saurashtra Sgnw Sharada Shavian Shaw Shrd Sidd Siddham SignWriting Sind Sinh Sinhala Sora Sora_Sompeng Soyo Soyombo Sund Sundanese Sylo Syloti_Nagri Syrc Syriac Tagalog Tagb Tagbanwa Tai_Le Tai_Tham Tai_Viet Takr Takri Tale Talu Tamil Taml Tang Tangut Tavt Telu Telugu Tfng Tglg Thaa Thaana Thai Tibetan Tibt Tifinagh Tirh Tirhuta Ugar Ugaritic Vai Vaii Wara Warang_Citi Xpeo Xsux Yi Yiii Zanabazar_Square Zanb Zinh Zyyy", "Dogr Dogra Gong Gunjala_Gondi Hanifi_Rohingya Maka Makasar Medefaidrin Medf Old_Sogdian Rohg Sogd Sogdian Sogo", "Elym Elymaic Hmnp Nand Nandinagari Nyiakeng_Puachue_Hmong Wancho Wcho", "Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi", "Cpmn Cypro_Minoan Old_Uyghur Ougr Tangsa Tnsa Toto Vith Vithkuqi", "Hrkt Katakana_Or_Hiragana Kawi Nag_Mundari Nagm Unknown Zzzz", "");
|
|
119
|
+
const binPropertySets = new DataSet("AHex ASCII ASCII_Hex_Digit Alpha Alphabetic Any Assigned Bidi_C Bidi_Control Bidi_M Bidi_Mirrored CI CWCF CWCM CWKCF CWL CWT CWU Case_Ignorable Cased Changes_When_Casefolded Changes_When_Casemapped Changes_When_Lowercased Changes_When_NFKC_Casefolded Changes_When_Titlecased Changes_When_Uppercased DI Dash Default_Ignorable_Code_Point Dep Deprecated Dia Diacritic Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Ext Extender Gr_Base Gr_Ext Grapheme_Base Grapheme_Extend Hex Hex_Digit IDC IDS IDSB IDST IDS_Binary_Operator IDS_Trinary_Operator ID_Continue ID_Start Ideo Ideographic Join_C Join_Control LOE Logical_Order_Exception Lower Lowercase Math NChar Noncharacter_Code_Point Pat_Syn Pat_WS Pattern_Syntax Pattern_White_Space QMark Quotation_Mark RI Radical Regional_Indicator SD STerm Sentence_Terminal Soft_Dotted Term Terminal_Punctuation UIdeo Unified_Ideograph Upper Uppercase VS Variation_Selector White_Space XIDC XIDS XID_Continue XID_Start space", "Extended_Pictographic", "", "EBase EComp EMod EPres ExtPict", "", "", "");
|
|
113
120
|
function isValidUnicodeProperty(version, name, value) {
|
|
114
121
|
if (gcNameSet.has(name)) {
|
|
115
122
|
return version >= 2018 && gcValueSets.es2018.has(value);
|
|
@@ -137,7 +144,10 @@ const LINE_TABULATION = 0x0b;
|
|
|
137
144
|
const FORM_FEED = 0x0c;
|
|
138
145
|
const CARRIAGE_RETURN = 0x0d;
|
|
139
146
|
const EXCLAMATION_MARK = 0x21;
|
|
147
|
+
const NUMBER_SIGN = 0x23;
|
|
140
148
|
const DOLLAR_SIGN = 0x24;
|
|
149
|
+
const PERCENT_SIGN = 0x25;
|
|
150
|
+
const AMPERSAND = 0x26;
|
|
141
151
|
const LEFT_PARENTHESIS = 0x28;
|
|
142
152
|
const RIGHT_PARENTHESIS = 0x29;
|
|
143
153
|
const ASTERISK = 0x2a;
|
|
@@ -151,10 +161,12 @@ const DIGIT_ONE = 0x31;
|
|
|
151
161
|
const DIGIT_SEVEN = 0x37;
|
|
152
162
|
const DIGIT_NINE = 0x39;
|
|
153
163
|
const COLON = 0x3a;
|
|
164
|
+
const SEMICOLON = 0x3b;
|
|
154
165
|
const LESS_THAN_SIGN = 0x3c;
|
|
155
166
|
const EQUALS_SIGN = 0x3d;
|
|
156
167
|
const GREATER_THAN_SIGN = 0x3e;
|
|
157
168
|
const QUESTION_MARK = 0x3f;
|
|
169
|
+
const COMMERCIAL_AT = 0x40;
|
|
158
170
|
const LATIN_CAPITAL_LETTER_A = 0x41;
|
|
159
171
|
const LATIN_CAPITAL_LETTER_B = 0x42;
|
|
160
172
|
const LATIN_CAPITAL_LETTER_D = 0x44;
|
|
@@ -175,6 +187,7 @@ const LATIN_SMALL_LETTER_K = 0x6b;
|
|
|
175
187
|
const LATIN_SMALL_LETTER_M = 0x6d;
|
|
176
188
|
const LATIN_SMALL_LETTER_N = 0x6e;
|
|
177
189
|
const LATIN_SMALL_LETTER_P = 0x70;
|
|
190
|
+
const LATIN_SMALL_LETTER_Q = 0x71;
|
|
178
191
|
const LATIN_SMALL_LETTER_R = 0x72;
|
|
179
192
|
const LATIN_SMALL_LETTER_S = 0x73;
|
|
180
193
|
const LATIN_SMALL_LETTER_T = 0x74;
|
|
@@ -188,9 +201,11 @@ const LEFT_SQUARE_BRACKET = 0x5b;
|
|
|
188
201
|
const REVERSE_SOLIDUS = 0x5c;
|
|
189
202
|
const RIGHT_SQUARE_BRACKET = 0x5d;
|
|
190
203
|
const CIRCUMFLEX_ACCENT = 0x5e;
|
|
204
|
+
const GRAVE_ACCENT = 0x60;
|
|
191
205
|
const LEFT_CURLY_BRACKET = 0x7b;
|
|
192
206
|
const VERTICAL_LINE = 0x7c;
|
|
193
207
|
const RIGHT_CURLY_BRACKET = 0x7d;
|
|
208
|
+
const TILDE = 0x7e;
|
|
194
209
|
const ZERO_WIDTH_NON_JOINER = 0x200c;
|
|
195
210
|
const ZERO_WIDTH_JOINER = 0x200d;
|
|
196
211
|
const LINE_SEPARATOR = 0x2028;
|
|
@@ -357,29 +372,102 @@ class RegExpSyntaxError extends SyntaxError {
|
|
|
357
372
|
}
|
|
358
373
|
}
|
|
359
374
|
|
|
375
|
+
const binPropertyOfStringSets = new Set([
|
|
376
|
+
"Basic_Emoji",
|
|
377
|
+
"Emoji_Keycap_Sequence",
|
|
378
|
+
"RGI_Emoji_Modifier_Sequence",
|
|
379
|
+
"RGI_Emoji_Flag_Sequence",
|
|
380
|
+
"RGI_Emoji_Tag_Sequence",
|
|
381
|
+
"RGI_Emoji_ZWJ_Sequence",
|
|
382
|
+
"RGI_Emoji",
|
|
383
|
+
]);
|
|
384
|
+
function isValidLoneUnicodePropertyOfString(version, value) {
|
|
385
|
+
return version >= 2024 && binPropertyOfStringSets.has(value);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const SYNTAX_CHARACTER = new Set([
|
|
389
|
+
CIRCUMFLEX_ACCENT,
|
|
390
|
+
DOLLAR_SIGN,
|
|
391
|
+
REVERSE_SOLIDUS,
|
|
392
|
+
FULL_STOP,
|
|
393
|
+
ASTERISK,
|
|
394
|
+
PLUS_SIGN,
|
|
395
|
+
QUESTION_MARK,
|
|
396
|
+
LEFT_PARENTHESIS,
|
|
397
|
+
RIGHT_PARENTHESIS,
|
|
398
|
+
LEFT_SQUARE_BRACKET,
|
|
399
|
+
RIGHT_SQUARE_BRACKET,
|
|
400
|
+
LEFT_CURLY_BRACKET,
|
|
401
|
+
RIGHT_CURLY_BRACKET,
|
|
402
|
+
VERTICAL_LINE,
|
|
403
|
+
]);
|
|
404
|
+
const CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR_CHARACTER = new Set([
|
|
405
|
+
AMPERSAND,
|
|
406
|
+
EXCLAMATION_MARK,
|
|
407
|
+
NUMBER_SIGN,
|
|
408
|
+
DOLLAR_SIGN,
|
|
409
|
+
PERCENT_SIGN,
|
|
410
|
+
ASTERISK,
|
|
411
|
+
PLUS_SIGN,
|
|
412
|
+
COMMA,
|
|
413
|
+
FULL_STOP,
|
|
414
|
+
COLON,
|
|
415
|
+
SEMICOLON,
|
|
416
|
+
LESS_THAN_SIGN,
|
|
417
|
+
EQUALS_SIGN,
|
|
418
|
+
GREATER_THAN_SIGN,
|
|
419
|
+
QUESTION_MARK,
|
|
420
|
+
COMMERCIAL_AT,
|
|
421
|
+
CIRCUMFLEX_ACCENT,
|
|
422
|
+
GRAVE_ACCENT,
|
|
423
|
+
TILDE,
|
|
424
|
+
]);
|
|
425
|
+
const CLASS_SET_SYNTAX_CHARACTER = new Set([
|
|
426
|
+
LEFT_PARENTHESIS,
|
|
427
|
+
RIGHT_PARENTHESIS,
|
|
428
|
+
LEFT_SQUARE_BRACKET,
|
|
429
|
+
RIGHT_SQUARE_BRACKET,
|
|
430
|
+
LEFT_CURLY_BRACKET,
|
|
431
|
+
RIGHT_CURLY_BRACKET,
|
|
432
|
+
SOLIDUS,
|
|
433
|
+
HYPHEN_MINUS,
|
|
434
|
+
REVERSE_SOLIDUS,
|
|
435
|
+
VERTICAL_LINE,
|
|
436
|
+
]);
|
|
437
|
+
const CLASS_SET_RESERVED_PUNCTUATOR = new Set([
|
|
438
|
+
AMPERSAND,
|
|
439
|
+
HYPHEN_MINUS,
|
|
440
|
+
EXCLAMATION_MARK,
|
|
441
|
+
NUMBER_SIGN,
|
|
442
|
+
PERCENT_SIGN,
|
|
443
|
+
COMMA,
|
|
444
|
+
COLON,
|
|
445
|
+
SEMICOLON,
|
|
446
|
+
LESS_THAN_SIGN,
|
|
447
|
+
EQUALS_SIGN,
|
|
448
|
+
GREATER_THAN_SIGN,
|
|
449
|
+
COMMERCIAL_AT,
|
|
450
|
+
GRAVE_ACCENT,
|
|
451
|
+
TILDE,
|
|
452
|
+
]);
|
|
360
453
|
function isSyntaxCharacter(cp) {
|
|
361
|
-
return (cp
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
cp === LEFT_PARENTHESIS ||
|
|
369
|
-
cp === RIGHT_PARENTHESIS ||
|
|
370
|
-
cp === LEFT_SQUARE_BRACKET ||
|
|
371
|
-
cp === RIGHT_SQUARE_BRACKET ||
|
|
372
|
-
cp === LEFT_CURLY_BRACKET ||
|
|
373
|
-
cp === RIGHT_CURLY_BRACKET ||
|
|
374
|
-
cp === VERTICAL_LINE);
|
|
454
|
+
return SYNTAX_CHARACTER.has(cp);
|
|
455
|
+
}
|
|
456
|
+
function isClassSetReservedDoublePunctuatorCharacter(cp) {
|
|
457
|
+
return CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR_CHARACTER.has(cp);
|
|
458
|
+
}
|
|
459
|
+
function isClassSetSyntaxCharacter(cp) {
|
|
460
|
+
return CLASS_SET_SYNTAX_CHARACTER.has(cp);
|
|
375
461
|
}
|
|
376
|
-
function
|
|
462
|
+
function isClassSetReservedPunctuator(cp) {
|
|
463
|
+
return CLASS_SET_RESERVED_PUNCTUATOR.has(cp);
|
|
464
|
+
}
|
|
465
|
+
function isIdentifierStartChar(cp) {
|
|
377
466
|
return isIdStart(cp) || cp === DOLLAR_SIGN || cp === LOW_LINE;
|
|
378
467
|
}
|
|
379
|
-
function
|
|
468
|
+
function isIdentifierPartChar(cp) {
|
|
380
469
|
return (isIdContinue(cp) ||
|
|
381
470
|
cp === DOLLAR_SIGN ||
|
|
382
|
-
cp === LOW_LINE ||
|
|
383
471
|
cp === ZERO_WIDTH_NON_JOINER ||
|
|
384
472
|
cp === ZERO_WIDTH_JOINER);
|
|
385
473
|
}
|
|
@@ -392,14 +480,15 @@ function isUnicodePropertyValueCharacter(cp) {
|
|
|
392
480
|
class RegExpValidator {
|
|
393
481
|
constructor(options) {
|
|
394
482
|
this._reader = new Reader();
|
|
395
|
-
this.
|
|
483
|
+
this._unicodeMode = false;
|
|
484
|
+
this._unicodeSetsMode = false;
|
|
396
485
|
this._nFlag = false;
|
|
397
486
|
this._lastIntValue = 0;
|
|
398
|
-
this.
|
|
399
|
-
|
|
487
|
+
this._lastRange = {
|
|
488
|
+
min: 0,
|
|
489
|
+
max: Number.POSITIVE_INFINITY,
|
|
490
|
+
};
|
|
400
491
|
this._lastStrValue = "";
|
|
401
|
-
this._lastKeyValue = "";
|
|
402
|
-
this._lastValValue = "";
|
|
403
492
|
this._lastAssertionIsQuantifiable = false;
|
|
404
493
|
this._numCapturingParens = 0;
|
|
405
494
|
this._groupNames = new Set();
|
|
@@ -407,14 +496,18 @@ class RegExpValidator {
|
|
|
407
496
|
this._options = options !== null && options !== void 0 ? options : {};
|
|
408
497
|
}
|
|
409
498
|
validateLiteral(source, start = 0, end = source.length) {
|
|
410
|
-
this.
|
|
499
|
+
this._unicodeSetsMode = this._unicodeMode = this._nFlag = false;
|
|
411
500
|
this.reset(source, start, end);
|
|
412
501
|
this.onLiteralEnter(start);
|
|
413
502
|
if (this.eat(SOLIDUS) && this.eatRegExpBody() && this.eat(SOLIDUS)) {
|
|
414
503
|
const flagStart = this.index;
|
|
415
|
-
const
|
|
504
|
+
const unicode = source.includes("u", flagStart);
|
|
505
|
+
const unicodeSets = source.includes("v", flagStart);
|
|
416
506
|
this.validateFlags(source, flagStart, end);
|
|
417
|
-
this.validatePattern(source, start + 1, flagStart - 1,
|
|
507
|
+
this.validatePattern(source, start + 1, flagStart - 1, {
|
|
508
|
+
unicode,
|
|
509
|
+
unicodeSets,
|
|
510
|
+
});
|
|
418
511
|
}
|
|
419
512
|
else if (start >= end) {
|
|
420
513
|
this.raise("Empty");
|
|
@@ -434,6 +527,7 @@ class RegExpValidator {
|
|
|
434
527
|
let unicode = false;
|
|
435
528
|
let dotAll = false;
|
|
436
529
|
let hasIndices = false;
|
|
530
|
+
let unicodeSets = false;
|
|
437
531
|
for (let i = start; i < end; ++i) {
|
|
438
532
|
const flag = source.charCodeAt(i);
|
|
439
533
|
if (existingFlags.has(flag)) {
|
|
@@ -465,6 +559,10 @@ class RegExpValidator {
|
|
|
465
559
|
this.ecmaVersion >= 2022) {
|
|
466
560
|
hasIndices = true;
|
|
467
561
|
}
|
|
562
|
+
else if (flag === LATIN_SMALL_LETTER_V &&
|
|
563
|
+
this.ecmaVersion >= 2024) {
|
|
564
|
+
unicodeSets = true;
|
|
565
|
+
}
|
|
468
566
|
else {
|
|
469
567
|
this.raise(`Invalid flag '${source[i]}'`);
|
|
470
568
|
}
|
|
@@ -477,13 +575,14 @@ class RegExpValidator {
|
|
|
477
575
|
sticky,
|
|
478
576
|
dotAll,
|
|
479
577
|
hasIndices,
|
|
578
|
+
unicodeSets,
|
|
480
579
|
});
|
|
481
580
|
}
|
|
482
|
-
validatePattern(source, start = 0, end = source.length,
|
|
483
|
-
|
|
484
|
-
this.
|
|
485
|
-
|
|
486
|
-
|
|
581
|
+
validatePattern(source, start = 0, end = source.length, uFlagOrFlags = undefined) {
|
|
582
|
+
const mode = this._parseFlagsOptionToMode(uFlagOrFlags);
|
|
583
|
+
this._unicodeMode = mode.unicodeMode;
|
|
584
|
+
this._nFlag = mode.nFlag;
|
|
585
|
+
this._unicodeSetsMode = mode.unicodeSetsMode;
|
|
487
586
|
this.reset(source, start, end);
|
|
488
587
|
this.consumePattern();
|
|
489
588
|
if (!this._nFlag &&
|
|
@@ -494,12 +593,36 @@ class RegExpValidator {
|
|
|
494
593
|
this.consumePattern();
|
|
495
594
|
}
|
|
496
595
|
}
|
|
596
|
+
_parseFlagsOptionToMode(uFlagOrFlags = undefined) {
|
|
597
|
+
let unicode = false;
|
|
598
|
+
let unicodeSets = false;
|
|
599
|
+
if (uFlagOrFlags && this.ecmaVersion >= 2015) {
|
|
600
|
+
if (typeof uFlagOrFlags === "object") {
|
|
601
|
+
unicode = Boolean(uFlagOrFlags.unicode);
|
|
602
|
+
if (this.ecmaVersion >= 2024) {
|
|
603
|
+
unicodeSets = Boolean(uFlagOrFlags.unicodeSets);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
unicode = uFlagOrFlags;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (unicode && unicodeSets) {
|
|
611
|
+
this.raise("Invalid regular expression flags");
|
|
612
|
+
}
|
|
613
|
+
const unicodeMode = unicode || unicodeSets;
|
|
614
|
+
const nFlag = (unicode && this.ecmaVersion >= 2018) ||
|
|
615
|
+
unicodeSets ||
|
|
616
|
+
Boolean(this._options.strict && this.ecmaVersion >= 2023);
|
|
617
|
+
const unicodeSetsMode = unicodeSets;
|
|
618
|
+
return { unicodeMode, nFlag, unicodeSetsMode };
|
|
619
|
+
}
|
|
497
620
|
get strict() {
|
|
498
|
-
return Boolean(this._options.strict) || this.
|
|
621
|
+
return Boolean(this._options.strict) || this._unicodeMode;
|
|
499
622
|
}
|
|
500
623
|
get ecmaVersion() {
|
|
501
624
|
var _a;
|
|
502
|
-
return (_a = this._options.ecmaVersion) !== null && _a !== void 0 ? _a :
|
|
625
|
+
return (_a = this._options.ecmaVersion) !== null && _a !== void 0 ? _a : latestEcmaVersion;
|
|
503
626
|
}
|
|
504
627
|
onLiteralEnter(start) {
|
|
505
628
|
if (this._options.onLiteralEnter) {
|
|
@@ -604,9 +727,9 @@ class RegExpValidator {
|
|
|
604
727
|
this._options.onEscapeCharacterSet(start, end, kind, negate);
|
|
605
728
|
}
|
|
606
729
|
}
|
|
607
|
-
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
|
|
730
|
+
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings) {
|
|
608
731
|
if (this._options.onUnicodePropertyCharacterSet) {
|
|
609
|
-
this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate);
|
|
732
|
+
this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings);
|
|
610
733
|
}
|
|
611
734
|
}
|
|
612
735
|
onCharacter(start, end, value) {
|
|
@@ -619,9 +742,9 @@ class RegExpValidator {
|
|
|
619
742
|
this._options.onBackreference(start, end, ref);
|
|
620
743
|
}
|
|
621
744
|
}
|
|
622
|
-
onCharacterClassEnter(start, negate) {
|
|
745
|
+
onCharacterClassEnter(start, negate, unicodeSets) {
|
|
623
746
|
if (this._options.onCharacterClassEnter) {
|
|
624
|
-
this._options.onCharacterClassEnter(start, negate);
|
|
747
|
+
this._options.onCharacterClassEnter(start, negate, unicodeSets);
|
|
625
748
|
}
|
|
626
749
|
}
|
|
627
750
|
onCharacterClassLeave(start, end, negate) {
|
|
@@ -634,6 +757,36 @@ class RegExpValidator {
|
|
|
634
757
|
this._options.onCharacterClassRange(start, end, min, max);
|
|
635
758
|
}
|
|
636
759
|
}
|
|
760
|
+
onClassIntersection(start, end) {
|
|
761
|
+
if (this._options.onClassIntersection) {
|
|
762
|
+
this._options.onClassIntersection(start, end);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
onClassSubtraction(start, end) {
|
|
766
|
+
if (this._options.onClassSubtraction) {
|
|
767
|
+
this._options.onClassSubtraction(start, end);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
onClassStringDisjunctionEnter(start) {
|
|
771
|
+
if (this._options.onClassStringDisjunctionEnter) {
|
|
772
|
+
this._options.onClassStringDisjunctionEnter(start);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
onClassStringDisjunctionLeave(start, end) {
|
|
776
|
+
if (this._options.onClassStringDisjunctionLeave) {
|
|
777
|
+
this._options.onClassStringDisjunctionLeave(start, end);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
onStringAlternativeEnter(start, index) {
|
|
781
|
+
if (this._options.onStringAlternativeEnter) {
|
|
782
|
+
this._options.onStringAlternativeEnter(start, index);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
onStringAlternativeLeave(start, end, index) {
|
|
786
|
+
if (this._options.onStringAlternativeLeave) {
|
|
787
|
+
this._options.onStringAlternativeLeave(start, end, index);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
637
790
|
get source() {
|
|
638
791
|
return this._reader.source;
|
|
639
792
|
}
|
|
@@ -653,7 +806,7 @@ class RegExpValidator {
|
|
|
653
806
|
return this._reader.nextCodePoint3;
|
|
654
807
|
}
|
|
655
808
|
reset(source, start, end) {
|
|
656
|
-
this._reader.reset(source, start, end, this.
|
|
809
|
+
this._reader.reset(source, start, end, this._unicodeMode);
|
|
657
810
|
}
|
|
658
811
|
rewind(index) {
|
|
659
812
|
this._reader.rewind(index);
|
|
@@ -671,7 +824,7 @@ class RegExpValidator {
|
|
|
671
824
|
return this._reader.eat3(cp1, cp2, cp3);
|
|
672
825
|
}
|
|
673
826
|
raise(message) {
|
|
674
|
-
throw new RegExpSyntaxError(this.source, this.
|
|
827
|
+
throw new RegExpSyntaxError(this.source, this._unicodeMode, this.index, message);
|
|
675
828
|
}
|
|
676
829
|
eatRegExpBody() {
|
|
677
830
|
const start = this.index;
|
|
@@ -786,7 +939,7 @@ class RegExpValidator {
|
|
|
786
939
|
this.onAlternativeLeave(start, this.index, i);
|
|
787
940
|
}
|
|
788
941
|
consumeTerm() {
|
|
789
|
-
if (this.
|
|
942
|
+
if (this._unicodeMode || this.strict) {
|
|
790
943
|
return (this.consumeAssertion() ||
|
|
791
944
|
(this.consumeAtom() && this.consumeOptionalQuantifier()));
|
|
792
945
|
}
|
|
@@ -855,8 +1008,7 @@ class RegExpValidator {
|
|
|
855
1008
|
max = 1;
|
|
856
1009
|
}
|
|
857
1010
|
else if (this.eatBracedQuantifier(noConsume)) {
|
|
858
|
-
min = this.
|
|
859
|
-
max = this._lastMaxValue;
|
|
1011
|
+
({ min, max } = this._lastRange);
|
|
860
1012
|
}
|
|
861
1013
|
else {
|
|
862
1014
|
return false;
|
|
@@ -870,23 +1022,23 @@ class RegExpValidator {
|
|
|
870
1022
|
eatBracedQuantifier(noError) {
|
|
871
1023
|
const start = this.index;
|
|
872
1024
|
if (this.eat(LEFT_CURLY_BRACKET)) {
|
|
873
|
-
this._lastMinValue = 0;
|
|
874
|
-
this._lastMaxValue = Number.POSITIVE_INFINITY;
|
|
875
1025
|
if (this.eatDecimalDigits()) {
|
|
876
|
-
|
|
1026
|
+
const min = this._lastIntValue;
|
|
1027
|
+
let max = min;
|
|
877
1028
|
if (this.eat(COMMA)) {
|
|
878
|
-
|
|
1029
|
+
max = this.eatDecimalDigits()
|
|
879
1030
|
? this._lastIntValue
|
|
880
1031
|
: Number.POSITIVE_INFINITY;
|
|
881
1032
|
}
|
|
882
1033
|
if (this.eat(RIGHT_CURLY_BRACKET)) {
|
|
883
|
-
if (!noError &&
|
|
1034
|
+
if (!noError && max < min) {
|
|
884
1035
|
this.raise("numbers out of order in {} quantifier");
|
|
885
1036
|
}
|
|
1037
|
+
this._lastRange = { min, max };
|
|
886
1038
|
return true;
|
|
887
1039
|
}
|
|
888
1040
|
}
|
|
889
|
-
if (!noError && (this.
|
|
1041
|
+
if (!noError && (this._unicodeMode || this.strict)) {
|
|
890
1042
|
this.raise("Incomplete quantifier");
|
|
891
1043
|
}
|
|
892
1044
|
this.rewind(start);
|
|
@@ -897,7 +1049,7 @@ class RegExpValidator {
|
|
|
897
1049
|
return (this.consumePatternCharacter() ||
|
|
898
1050
|
this.consumeDot() ||
|
|
899
1051
|
this.consumeReverseSolidusAtomEscape() ||
|
|
900
|
-
this.consumeCharacterClass() ||
|
|
1052
|
+
Boolean(this.consumeCharacterClass()) ||
|
|
901
1053
|
this.consumeUncapturingGroup() ||
|
|
902
1054
|
this.consumeCapturingGroup());
|
|
903
1055
|
}
|
|
@@ -957,7 +1109,7 @@ class RegExpValidator {
|
|
|
957
1109
|
return (this.consumeDot() ||
|
|
958
1110
|
this.consumeReverseSolidusAtomEscape() ||
|
|
959
1111
|
this.consumeReverseSolidusFollowedByC() ||
|
|
960
|
-
this.consumeCharacterClass() ||
|
|
1112
|
+
Boolean(this.consumeCharacterClass()) ||
|
|
961
1113
|
this.consumeUncapturingGroup() ||
|
|
962
1114
|
this.consumeCapturingGroup() ||
|
|
963
1115
|
this.consumeInvalidBracedQuantifier() ||
|
|
@@ -1031,7 +1183,7 @@ class RegExpValidator {
|
|
|
1031
1183
|
(this._nFlag && this.consumeKGroupName())) {
|
|
1032
1184
|
return true;
|
|
1033
1185
|
}
|
|
1034
|
-
if (this.strict || this.
|
|
1186
|
+
if (this.strict || this._unicodeMode) {
|
|
1035
1187
|
this.raise("Invalid escape");
|
|
1036
1188
|
}
|
|
1037
1189
|
return false;
|
|
@@ -1044,7 +1196,7 @@ class RegExpValidator {
|
|
|
1044
1196
|
this.onBackreference(start - 1, this.index, n);
|
|
1045
1197
|
return true;
|
|
1046
1198
|
}
|
|
1047
|
-
if (this.strict || this.
|
|
1199
|
+
if (this.strict || this._unicodeMode) {
|
|
1048
1200
|
this.raise("Invalid escape");
|
|
1049
1201
|
}
|
|
1050
1202
|
this.rewind(start);
|
|
@@ -1052,52 +1204,57 @@ class RegExpValidator {
|
|
|
1052
1204
|
return false;
|
|
1053
1205
|
}
|
|
1054
1206
|
consumeCharacterClassEscape() {
|
|
1207
|
+
var _a;
|
|
1055
1208
|
const start = this.index;
|
|
1056
1209
|
if (this.eat(LATIN_SMALL_LETTER_D)) {
|
|
1057
1210
|
this._lastIntValue = -1;
|
|
1058
1211
|
this.onEscapeCharacterSet(start - 1, this.index, "digit", false);
|
|
1059
|
-
return
|
|
1212
|
+
return {};
|
|
1060
1213
|
}
|
|
1061
1214
|
if (this.eat(LATIN_CAPITAL_LETTER_D)) {
|
|
1062
1215
|
this._lastIntValue = -1;
|
|
1063
1216
|
this.onEscapeCharacterSet(start - 1, this.index, "digit", true);
|
|
1064
|
-
return
|
|
1217
|
+
return {};
|
|
1065
1218
|
}
|
|
1066
1219
|
if (this.eat(LATIN_SMALL_LETTER_S)) {
|
|
1067
1220
|
this._lastIntValue = -1;
|
|
1068
1221
|
this.onEscapeCharacterSet(start - 1, this.index, "space", false);
|
|
1069
|
-
return
|
|
1222
|
+
return {};
|
|
1070
1223
|
}
|
|
1071
1224
|
if (this.eat(LATIN_CAPITAL_LETTER_S)) {
|
|
1072
1225
|
this._lastIntValue = -1;
|
|
1073
1226
|
this.onEscapeCharacterSet(start - 1, this.index, "space", true);
|
|
1074
|
-
return
|
|
1227
|
+
return {};
|
|
1075
1228
|
}
|
|
1076
1229
|
if (this.eat(LATIN_SMALL_LETTER_W)) {
|
|
1077
1230
|
this._lastIntValue = -1;
|
|
1078
1231
|
this.onEscapeCharacterSet(start - 1, this.index, "word", false);
|
|
1079
|
-
return
|
|
1232
|
+
return {};
|
|
1080
1233
|
}
|
|
1081
1234
|
if (this.eat(LATIN_CAPITAL_LETTER_W)) {
|
|
1082
1235
|
this._lastIntValue = -1;
|
|
1083
1236
|
this.onEscapeCharacterSet(start - 1, this.index, "word", true);
|
|
1084
|
-
return
|
|
1237
|
+
return {};
|
|
1085
1238
|
}
|
|
1086
1239
|
let negate = false;
|
|
1087
|
-
if (this.
|
|
1240
|
+
if (this._unicodeMode &&
|
|
1088
1241
|
this.ecmaVersion >= 2018 &&
|
|
1089
1242
|
(this.eat(LATIN_SMALL_LETTER_P) ||
|
|
1090
1243
|
(negate = this.eat(LATIN_CAPITAL_LETTER_P)))) {
|
|
1091
1244
|
this._lastIntValue = -1;
|
|
1245
|
+
let result = null;
|
|
1092
1246
|
if (this.eat(LEFT_CURLY_BRACKET) &&
|
|
1093
|
-
this.eatUnicodePropertyValueExpression() &&
|
|
1247
|
+
(result = this.eatUnicodePropertyValueExpression()) &&
|
|
1094
1248
|
this.eat(RIGHT_CURLY_BRACKET)) {
|
|
1095
|
-
|
|
1096
|
-
|
|
1249
|
+
if (negate && result.strings) {
|
|
1250
|
+
this.raise("Invalid property name");
|
|
1251
|
+
}
|
|
1252
|
+
this.onUnicodePropertyCharacterSet(start - 1, this.index, "property", result.key, result.value, negate, (_a = result.strings) !== null && _a !== void 0 ? _a : false);
|
|
1253
|
+
return { mayContainStrings: result.strings };
|
|
1097
1254
|
}
|
|
1098
1255
|
this.raise("Invalid property name");
|
|
1099
1256
|
}
|
|
1100
|
-
return
|
|
1257
|
+
return null;
|
|
1101
1258
|
}
|
|
1102
1259
|
consumeCharacterEscape() {
|
|
1103
1260
|
const start = this.index;
|
|
@@ -1107,7 +1264,7 @@ class RegExpValidator {
|
|
|
1107
1264
|
this.eatHexEscapeSequence() ||
|
|
1108
1265
|
this.eatRegExpUnicodeEscapeSequence() ||
|
|
1109
1266
|
(!this.strict &&
|
|
1110
|
-
!this.
|
|
1267
|
+
!this._unicodeMode &&
|
|
1111
1268
|
this.eatLegacyOctalEscapeSequence()) ||
|
|
1112
1269
|
this.eatIdentityEscape()) {
|
|
1113
1270
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
@@ -1132,18 +1289,31 @@ class RegExpValidator {
|
|
|
1132
1289
|
const start = this.index;
|
|
1133
1290
|
if (this.eat(LEFT_SQUARE_BRACKET)) {
|
|
1134
1291
|
const negate = this.eat(CIRCUMFLEX_ACCENT);
|
|
1135
|
-
this.onCharacterClassEnter(start, negate);
|
|
1136
|
-
this.
|
|
1292
|
+
this.onCharacterClassEnter(start, negate, this._unicodeSetsMode);
|
|
1293
|
+
const result = this.consumeClassContents();
|
|
1137
1294
|
if (!this.eat(RIGHT_SQUARE_BRACKET)) {
|
|
1138
|
-
this.
|
|
1295
|
+
if (this.currentCodePoint === -1) {
|
|
1296
|
+
this.raise("Unterminated character class");
|
|
1297
|
+
}
|
|
1298
|
+
this.raise("Invalid character in character class");
|
|
1299
|
+
}
|
|
1300
|
+
if (negate && result.mayContainStrings) {
|
|
1301
|
+
this.raise("Negated character class may contain strings");
|
|
1139
1302
|
}
|
|
1140
1303
|
this.onCharacterClassLeave(start, this.index, negate);
|
|
1141
|
-
return
|
|
1304
|
+
return result;
|
|
1142
1305
|
}
|
|
1143
|
-
return
|
|
1306
|
+
return null;
|
|
1144
1307
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1308
|
+
consumeClassContents() {
|
|
1309
|
+
if (this._unicodeSetsMode) {
|
|
1310
|
+
if (this.currentCodePoint === RIGHT_SQUARE_BRACKET) {
|
|
1311
|
+
return {};
|
|
1312
|
+
}
|
|
1313
|
+
const result = this.consumeClassSetExpression();
|
|
1314
|
+
return result;
|
|
1315
|
+
}
|
|
1316
|
+
const strict = this.strict || this._unicodeMode;
|
|
1147
1317
|
for (;;) {
|
|
1148
1318
|
const rangeStart = this.index;
|
|
1149
1319
|
if (!this.consumeClassAtom()) {
|
|
@@ -1169,6 +1339,7 @@ class RegExpValidator {
|
|
|
1169
1339
|
}
|
|
1170
1340
|
this.onCharacterClassRange(rangeStart, this.index, min, max);
|
|
1171
1341
|
}
|
|
1342
|
+
return {};
|
|
1172
1343
|
}
|
|
1173
1344
|
consumeClassAtom() {
|
|
1174
1345
|
const start = this.index;
|
|
@@ -1191,7 +1362,7 @@ class RegExpValidator {
|
|
|
1191
1362
|
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1192
1363
|
return true;
|
|
1193
1364
|
}
|
|
1194
|
-
if (this.strict || this.
|
|
1365
|
+
if (this.strict || this._unicodeMode) {
|
|
1195
1366
|
this.raise("Invalid escape");
|
|
1196
1367
|
}
|
|
1197
1368
|
this.rewind(start);
|
|
@@ -1205,14 +1376,14 @@ class RegExpValidator {
|
|
|
1205
1376
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1206
1377
|
return true;
|
|
1207
1378
|
}
|
|
1208
|
-
if (this.
|
|
1379
|
+
if (this._unicodeMode && this.eat(HYPHEN_MINUS)) {
|
|
1209
1380
|
this._lastIntValue = HYPHEN_MINUS;
|
|
1210
1381
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1211
1382
|
return true;
|
|
1212
1383
|
}
|
|
1213
1384
|
let cp = 0;
|
|
1214
1385
|
if (!this.strict &&
|
|
1215
|
-
!this.
|
|
1386
|
+
!this._unicodeMode &&
|
|
1216
1387
|
this.currentCodePoint === LATIN_SMALL_LETTER_C &&
|
|
1217
1388
|
(isDecimalDigit((cp = this.nextCodePoint)) || cp === LOW_LINE)) {
|
|
1218
1389
|
this.advance();
|
|
@@ -1221,7 +1392,196 @@ class RegExpValidator {
|
|
|
1221
1392
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1222
1393
|
return true;
|
|
1223
1394
|
}
|
|
1224
|
-
return (this.consumeCharacterClassEscape() ||
|
|
1395
|
+
return (Boolean(this.consumeCharacterClassEscape()) ||
|
|
1396
|
+
this.consumeCharacterEscape());
|
|
1397
|
+
}
|
|
1398
|
+
consumeClassSetExpression() {
|
|
1399
|
+
const start = this.index;
|
|
1400
|
+
let mayContainStrings = false;
|
|
1401
|
+
let result = null;
|
|
1402
|
+
if (this.consumeClassSetCharacter()) {
|
|
1403
|
+
if (this.consumeClassSetRangeFromOperator(start)) {
|
|
1404
|
+
this.consumeClassUnionRight({});
|
|
1405
|
+
return {};
|
|
1406
|
+
}
|
|
1407
|
+
mayContainStrings = false;
|
|
1408
|
+
}
|
|
1409
|
+
else if ((result = this.consumeClassSetOperand())) {
|
|
1410
|
+
mayContainStrings = result.mayContainStrings;
|
|
1411
|
+
}
|
|
1412
|
+
else {
|
|
1413
|
+
const cp = this.currentCodePoint;
|
|
1414
|
+
if (cp === REVERSE_SOLIDUS) {
|
|
1415
|
+
this.advance();
|
|
1416
|
+
this.raise("Invalid escape");
|
|
1417
|
+
}
|
|
1418
|
+
if (cp === this.nextCodePoint &&
|
|
1419
|
+
isClassSetReservedDoublePunctuatorCharacter(cp)) {
|
|
1420
|
+
this.raise("Invalid set operation in character class");
|
|
1421
|
+
}
|
|
1422
|
+
this.raise("Invalid character in character class");
|
|
1423
|
+
}
|
|
1424
|
+
if (this.eat2(AMPERSAND, AMPERSAND)) {
|
|
1425
|
+
while (this.currentCodePoint !== AMPERSAND &&
|
|
1426
|
+
(result = this.consumeClassSetOperand())) {
|
|
1427
|
+
this.onClassIntersection(start, this.index);
|
|
1428
|
+
if (!result.mayContainStrings) {
|
|
1429
|
+
mayContainStrings = false;
|
|
1430
|
+
}
|
|
1431
|
+
if (this.eat2(AMPERSAND, AMPERSAND)) {
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
return { mayContainStrings };
|
|
1435
|
+
}
|
|
1436
|
+
this.raise("Invalid character in character class");
|
|
1437
|
+
}
|
|
1438
|
+
if (this.eat2(HYPHEN_MINUS, HYPHEN_MINUS)) {
|
|
1439
|
+
while (this.consumeClassSetOperand()) {
|
|
1440
|
+
this.onClassSubtraction(start, this.index);
|
|
1441
|
+
if (this.eat2(HYPHEN_MINUS, HYPHEN_MINUS)) {
|
|
1442
|
+
continue;
|
|
1443
|
+
}
|
|
1444
|
+
return { mayContainStrings };
|
|
1445
|
+
}
|
|
1446
|
+
this.raise("Invalid character in character class");
|
|
1447
|
+
}
|
|
1448
|
+
return this.consumeClassUnionRight({ mayContainStrings });
|
|
1449
|
+
}
|
|
1450
|
+
consumeClassUnionRight(leftResult) {
|
|
1451
|
+
let mayContainStrings = leftResult.mayContainStrings;
|
|
1452
|
+
for (;;) {
|
|
1453
|
+
const start = this.index;
|
|
1454
|
+
if (this.consumeClassSetCharacter()) {
|
|
1455
|
+
this.consumeClassSetRangeFromOperator(start);
|
|
1456
|
+
continue;
|
|
1457
|
+
}
|
|
1458
|
+
const result = this.consumeClassSetOperand();
|
|
1459
|
+
if (result) {
|
|
1460
|
+
if (result.mayContainStrings) {
|
|
1461
|
+
mayContainStrings = true;
|
|
1462
|
+
}
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
break;
|
|
1466
|
+
}
|
|
1467
|
+
return { mayContainStrings };
|
|
1468
|
+
}
|
|
1469
|
+
consumeClassSetRangeFromOperator(start) {
|
|
1470
|
+
const currentStart = this.index;
|
|
1471
|
+
const min = this._lastIntValue;
|
|
1472
|
+
if (this.eat(HYPHEN_MINUS)) {
|
|
1473
|
+
if (this.consumeClassSetCharacter()) {
|
|
1474
|
+
const max = this._lastIntValue;
|
|
1475
|
+
if (min === -1 || max === -1) {
|
|
1476
|
+
this.raise("Invalid character class");
|
|
1477
|
+
}
|
|
1478
|
+
if (min > max) {
|
|
1479
|
+
this.raise("Range out of order in character class");
|
|
1480
|
+
}
|
|
1481
|
+
this.onCharacterClassRange(start, this.index, min, max);
|
|
1482
|
+
return true;
|
|
1483
|
+
}
|
|
1484
|
+
this.rewind(currentStart);
|
|
1485
|
+
}
|
|
1486
|
+
return false;
|
|
1487
|
+
}
|
|
1488
|
+
consumeClassSetOperand() {
|
|
1489
|
+
let result = null;
|
|
1490
|
+
if ((result = this.consumeNestedClass())) {
|
|
1491
|
+
return result;
|
|
1492
|
+
}
|
|
1493
|
+
if ((result = this.consumeClassStringDisjunction())) {
|
|
1494
|
+
return result;
|
|
1495
|
+
}
|
|
1496
|
+
if (this.consumeClassSetCharacter()) {
|
|
1497
|
+
return {};
|
|
1498
|
+
}
|
|
1499
|
+
return null;
|
|
1500
|
+
}
|
|
1501
|
+
consumeNestedClass() {
|
|
1502
|
+
const start = this.index;
|
|
1503
|
+
if (this.eat(LEFT_SQUARE_BRACKET)) {
|
|
1504
|
+
const negate = this.eat(CIRCUMFLEX_ACCENT);
|
|
1505
|
+
this.onCharacterClassEnter(start, negate, true);
|
|
1506
|
+
const result = this.consumeClassContents();
|
|
1507
|
+
if (!this.eat(RIGHT_SQUARE_BRACKET)) {
|
|
1508
|
+
this.raise("Unterminated character class");
|
|
1509
|
+
}
|
|
1510
|
+
if (negate && result.mayContainStrings) {
|
|
1511
|
+
this.raise("Negated character class may contain strings");
|
|
1512
|
+
}
|
|
1513
|
+
this.onCharacterClassLeave(start, this.index, negate);
|
|
1514
|
+
return result;
|
|
1515
|
+
}
|
|
1516
|
+
if (this.eat(REVERSE_SOLIDUS)) {
|
|
1517
|
+
const result = this.consumeCharacterClassEscape();
|
|
1518
|
+
if (result) {
|
|
1519
|
+
return result;
|
|
1520
|
+
}
|
|
1521
|
+
this.rewind(start);
|
|
1522
|
+
}
|
|
1523
|
+
return null;
|
|
1524
|
+
}
|
|
1525
|
+
consumeClassStringDisjunction() {
|
|
1526
|
+
const start = this.index;
|
|
1527
|
+
if (this.eat3(REVERSE_SOLIDUS, LATIN_SMALL_LETTER_Q, LEFT_CURLY_BRACKET)) {
|
|
1528
|
+
this.onClassStringDisjunctionEnter(start);
|
|
1529
|
+
let i = 0;
|
|
1530
|
+
let mayContainStrings = false;
|
|
1531
|
+
do {
|
|
1532
|
+
if (this.consumeClassString(i++).mayContainStrings) {
|
|
1533
|
+
mayContainStrings = true;
|
|
1534
|
+
}
|
|
1535
|
+
} while (this.eat(VERTICAL_LINE));
|
|
1536
|
+
if (this.eat(RIGHT_CURLY_BRACKET)) {
|
|
1537
|
+
this.onClassStringDisjunctionLeave(start, this.index);
|
|
1538
|
+
return { mayContainStrings };
|
|
1539
|
+
}
|
|
1540
|
+
this.raise("Unterminated class string disjunction");
|
|
1541
|
+
}
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
consumeClassString(i) {
|
|
1545
|
+
const start = this.index;
|
|
1546
|
+
let count = 0;
|
|
1547
|
+
this.onStringAlternativeEnter(start, i);
|
|
1548
|
+
while (this.currentCodePoint !== -1 &&
|
|
1549
|
+
this.consumeClassSetCharacter()) {
|
|
1550
|
+
count++;
|
|
1551
|
+
}
|
|
1552
|
+
this.onStringAlternativeLeave(start, this.index, i);
|
|
1553
|
+
return { mayContainStrings: count !== 1 };
|
|
1554
|
+
}
|
|
1555
|
+
consumeClassSetCharacter() {
|
|
1556
|
+
const start = this.index;
|
|
1557
|
+
const cp = this.currentCodePoint;
|
|
1558
|
+
if (cp !== this.nextCodePoint ||
|
|
1559
|
+
!isClassSetReservedDoublePunctuatorCharacter(cp)) {
|
|
1560
|
+
if (cp !== -1 && !isClassSetSyntaxCharacter(cp)) {
|
|
1561
|
+
this._lastIntValue = cp;
|
|
1562
|
+
this.advance();
|
|
1563
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1564
|
+
return true;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
if (this.eat(REVERSE_SOLIDUS)) {
|
|
1568
|
+
if (this.consumeCharacterEscape()) {
|
|
1569
|
+
return true;
|
|
1570
|
+
}
|
|
1571
|
+
if (isClassSetReservedPunctuator(this.currentCodePoint)) {
|
|
1572
|
+
this._lastIntValue = this.currentCodePoint;
|
|
1573
|
+
this.advance();
|
|
1574
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1575
|
+
return true;
|
|
1576
|
+
}
|
|
1577
|
+
if (this.eat(LATIN_SMALL_LETTER_B)) {
|
|
1578
|
+
this._lastIntValue = BACKSPACE;
|
|
1579
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1580
|
+
return true;
|
|
1581
|
+
}
|
|
1582
|
+
this.rewind(start);
|
|
1583
|
+
}
|
|
1584
|
+
return false;
|
|
1225
1585
|
}
|
|
1226
1586
|
eatGroupName() {
|
|
1227
1587
|
if (this.eat(LESS_THAN_SIGN)) {
|
|
@@ -1244,7 +1604,7 @@ class RegExpValidator {
|
|
|
1244
1604
|
}
|
|
1245
1605
|
eatRegExpIdentifierStart() {
|
|
1246
1606
|
const start = this.index;
|
|
1247
|
-
const forceUFlag = !this.
|
|
1607
|
+
const forceUFlag = !this._unicodeMode && this.ecmaVersion >= 2020;
|
|
1248
1608
|
let cp = this.currentCodePoint;
|
|
1249
1609
|
this.advance();
|
|
1250
1610
|
if (cp === REVERSE_SOLIDUS &&
|
|
@@ -1257,7 +1617,7 @@ class RegExpValidator {
|
|
|
1257
1617
|
cp = combineSurrogatePair(cp, this.currentCodePoint);
|
|
1258
1618
|
this.advance();
|
|
1259
1619
|
}
|
|
1260
|
-
if (
|
|
1620
|
+
if (isIdentifierStartChar(cp)) {
|
|
1261
1621
|
this._lastIntValue = cp;
|
|
1262
1622
|
return true;
|
|
1263
1623
|
}
|
|
@@ -1268,7 +1628,7 @@ class RegExpValidator {
|
|
|
1268
1628
|
}
|
|
1269
1629
|
eatRegExpIdentifierPart() {
|
|
1270
1630
|
const start = this.index;
|
|
1271
|
-
const forceUFlag = !this.
|
|
1631
|
+
const forceUFlag = !this._unicodeMode && this.ecmaVersion >= 2020;
|
|
1272
1632
|
let cp = this.currentCodePoint;
|
|
1273
1633
|
this.advance();
|
|
1274
1634
|
if (cp === REVERSE_SOLIDUS &&
|
|
@@ -1281,7 +1641,7 @@ class RegExpValidator {
|
|
|
1281
1641
|
cp = combineSurrogatePair(cp, this.currentCodePoint);
|
|
1282
1642
|
this.advance();
|
|
1283
1643
|
}
|
|
1284
|
-
if (
|
|
1644
|
+
if (isIdentifierPartChar(cp)) {
|
|
1285
1645
|
this._lastIntValue = cp;
|
|
1286
1646
|
return true;
|
|
1287
1647
|
}
|
|
@@ -1343,7 +1703,7 @@ class RegExpValidator {
|
|
|
1343
1703
|
}
|
|
1344
1704
|
eatRegExpUnicodeEscapeSequence(forceUFlag = false) {
|
|
1345
1705
|
const start = this.index;
|
|
1346
|
-
const uFlag = forceUFlag || this.
|
|
1706
|
+
const uFlag = forceUFlag || this._unicodeMode;
|
|
1347
1707
|
if (this.eat(LATIN_SMALL_LETTER_U)) {
|
|
1348
1708
|
if ((uFlag && this.eatRegExpUnicodeSurrogatePairEscape()) ||
|
|
1349
1709
|
this.eatFixedHexDigits(4) ||
|
|
@@ -1399,7 +1759,7 @@ class RegExpValidator {
|
|
|
1399
1759
|
if (cp === -1) {
|
|
1400
1760
|
return false;
|
|
1401
1761
|
}
|
|
1402
|
-
if (this.
|
|
1762
|
+
if (this._unicodeMode) {
|
|
1403
1763
|
return isSyntaxCharacter(cp) || cp === SOLIDUS;
|
|
1404
1764
|
}
|
|
1405
1765
|
if (this.strict) {
|
|
@@ -1426,11 +1786,14 @@ class RegExpValidator {
|
|
|
1426
1786
|
eatUnicodePropertyValueExpression() {
|
|
1427
1787
|
const start = this.index;
|
|
1428
1788
|
if (this.eatUnicodePropertyName() && this.eat(EQUALS_SIGN)) {
|
|
1429
|
-
|
|
1789
|
+
const key = this._lastStrValue;
|
|
1430
1790
|
if (this.eatUnicodePropertyValue()) {
|
|
1431
|
-
|
|
1432
|
-
if (isValidUnicodeProperty(this.ecmaVersion,
|
|
1433
|
-
return
|
|
1791
|
+
const value = this._lastStrValue;
|
|
1792
|
+
if (isValidUnicodeProperty(this.ecmaVersion, key, value)) {
|
|
1793
|
+
return {
|
|
1794
|
+
key,
|
|
1795
|
+
value: value || null,
|
|
1796
|
+
};
|
|
1434
1797
|
}
|
|
1435
1798
|
this.raise("Invalid property name");
|
|
1436
1799
|
}
|
|
@@ -1439,18 +1802,28 @@ class RegExpValidator {
|
|
|
1439
1802
|
if (this.eatLoneUnicodePropertyNameOrValue()) {
|
|
1440
1803
|
const nameOrValue = this._lastStrValue;
|
|
1441
1804
|
if (isValidUnicodeProperty(this.ecmaVersion, "General_Category", nameOrValue)) {
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1805
|
+
return {
|
|
1806
|
+
key: "General_Category",
|
|
1807
|
+
value: nameOrValue || null,
|
|
1808
|
+
};
|
|
1445
1809
|
}
|
|
1446
1810
|
if (isValidLoneUnicodeProperty(this.ecmaVersion, nameOrValue)) {
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1811
|
+
return {
|
|
1812
|
+
key: nameOrValue,
|
|
1813
|
+
value: null,
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
if (this._unicodeSetsMode &&
|
|
1817
|
+
isValidLoneUnicodePropertyOfString(this.ecmaVersion, nameOrValue)) {
|
|
1818
|
+
return {
|
|
1819
|
+
key: nameOrValue,
|
|
1820
|
+
value: null,
|
|
1821
|
+
strings: true,
|
|
1822
|
+
};
|
|
1450
1823
|
}
|
|
1451
1824
|
this.raise("Invalid property name");
|
|
1452
1825
|
}
|
|
1453
|
-
return
|
|
1826
|
+
return null;
|
|
1454
1827
|
}
|
|
1455
1828
|
eatUnicodePropertyName() {
|
|
1456
1829
|
this._lastStrValue = "";
|
|
@@ -1477,7 +1850,7 @@ class RegExpValidator {
|
|
|
1477
1850
|
if (this.eatFixedHexDigits(2)) {
|
|
1478
1851
|
return true;
|
|
1479
1852
|
}
|
|
1480
|
-
if (this.
|
|
1853
|
+
if (this._unicodeMode || this.strict) {
|
|
1481
1854
|
this.raise("Invalid escape");
|
|
1482
1855
|
}
|
|
1483
1856
|
this.rewind(start);
|
|
@@ -1552,16 +1925,24 @@ class RegExpValidator {
|
|
|
1552
1925
|
const DUMMY_PATTERN = {};
|
|
1553
1926
|
const DUMMY_FLAGS = {};
|
|
1554
1927
|
const DUMMY_CAPTURING_GROUP = {};
|
|
1928
|
+
function isClassSetOperand(node) {
|
|
1929
|
+
return (node.type === "Character" ||
|
|
1930
|
+
node.type === "CharacterSet" ||
|
|
1931
|
+
node.type === "CharacterClass" ||
|
|
1932
|
+
node.type === "ExpressionCharacterClass" ||
|
|
1933
|
+
node.type === "ClassStringDisjunction");
|
|
1934
|
+
}
|
|
1555
1935
|
class RegExpParserState {
|
|
1556
1936
|
constructor(options) {
|
|
1557
1937
|
var _a;
|
|
1558
1938
|
this._node = DUMMY_PATTERN;
|
|
1939
|
+
this._expressionBuffer = null;
|
|
1559
1940
|
this._flags = DUMMY_FLAGS;
|
|
1560
1941
|
this._backreferences = [];
|
|
1561
1942
|
this._capturingGroups = [];
|
|
1562
1943
|
this.source = "";
|
|
1563
1944
|
this.strict = Boolean(options === null || options === void 0 ? void 0 : options.strict);
|
|
1564
|
-
this.ecmaVersion = (_a = options === null || options === void 0 ? void 0 : options.ecmaVersion) !== null && _a !== void 0 ? _a :
|
|
1945
|
+
this.ecmaVersion = (_a = options === null || options === void 0 ? void 0 : options.ecmaVersion) !== null && _a !== void 0 ? _a : latestEcmaVersion;
|
|
1565
1946
|
}
|
|
1566
1947
|
get pattern() {
|
|
1567
1948
|
if (this._node.type !== "Pattern") {
|
|
@@ -1575,7 +1956,7 @@ class RegExpParserState {
|
|
|
1575
1956
|
}
|
|
1576
1957
|
return this._flags;
|
|
1577
1958
|
}
|
|
1578
|
-
onRegExpFlags(start, end, { global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices, }) {
|
|
1959
|
+
onRegExpFlags(start, end, { global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices, unicodeSets, }) {
|
|
1579
1960
|
this._flags = {
|
|
1580
1961
|
type: "Flags",
|
|
1581
1962
|
parent: null,
|
|
@@ -1589,6 +1970,7 @@ class RegExpParserState {
|
|
|
1589
1970
|
sticky,
|
|
1590
1971
|
dotAll,
|
|
1591
1972
|
hasIndices,
|
|
1973
|
+
unicodeSets,
|
|
1592
1974
|
};
|
|
1593
1975
|
}
|
|
1594
1976
|
onPatternEnter(start) {
|
|
@@ -1803,26 +2185,33 @@ class RegExpParserState {
|
|
|
1803
2185
|
negate,
|
|
1804
2186
|
});
|
|
1805
2187
|
}
|
|
1806
|
-
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
|
|
2188
|
+
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings) {
|
|
1807
2189
|
const parent = this._node;
|
|
1808
|
-
if (parent.type !== "Alternative" &&
|
|
2190
|
+
if ((parent.type !== "Alternative" &&
|
|
2191
|
+
parent.type !== "CharacterClass") ||
|
|
2192
|
+
(strings && (negate || value))) {
|
|
1809
2193
|
throw new Error("UnknownError");
|
|
1810
2194
|
}
|
|
1811
|
-
|
|
2195
|
+
const base = {
|
|
1812
2196
|
type: "CharacterSet",
|
|
1813
2197
|
parent,
|
|
1814
2198
|
start,
|
|
1815
2199
|
end,
|
|
1816
2200
|
raw: this.source.slice(start, end),
|
|
1817
2201
|
kind,
|
|
2202
|
+
strings,
|
|
1818
2203
|
key,
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
2204
|
+
};
|
|
2205
|
+
const node = strings
|
|
2206
|
+
? Object.assign(Object.assign({}, base), { value: null, negate: false, strings: true }) : Object.assign(Object.assign({}, base), { value,
|
|
2207
|
+
negate, strings: false });
|
|
2208
|
+
parent.elements.push(node);
|
|
1822
2209
|
}
|
|
1823
2210
|
onCharacter(start, end, value) {
|
|
1824
2211
|
const parent = this._node;
|
|
1825
|
-
if (parent.type !== "Alternative" &&
|
|
2212
|
+
if (parent.type !== "Alternative" &&
|
|
2213
|
+
parent.type !== "CharacterClass" &&
|
|
2214
|
+
parent.type !== "StringAlternative") {
|
|
1826
2215
|
throw new Error("UnknownError");
|
|
1827
2216
|
}
|
|
1828
2217
|
parent.elements.push({
|
|
@@ -1851,31 +2240,66 @@ class RegExpParserState {
|
|
|
1851
2240
|
parent.elements.push(node);
|
|
1852
2241
|
this._backreferences.push(node);
|
|
1853
2242
|
}
|
|
1854
|
-
onCharacterClassEnter(start, negate) {
|
|
2243
|
+
onCharacterClassEnter(start, negate, unicodeSets) {
|
|
1855
2244
|
const parent = this._node;
|
|
1856
|
-
|
|
1857
|
-
throw new Error("UnknownError");
|
|
1858
|
-
}
|
|
1859
|
-
this._node = {
|
|
2245
|
+
const base = {
|
|
1860
2246
|
type: "CharacterClass",
|
|
1861
2247
|
parent,
|
|
1862
2248
|
start,
|
|
1863
2249
|
end: start,
|
|
1864
2250
|
raw: "",
|
|
2251
|
+
unicodeSets,
|
|
1865
2252
|
negate,
|
|
1866
2253
|
elements: [],
|
|
1867
2254
|
};
|
|
1868
|
-
parent.
|
|
2255
|
+
if (parent.type === "Alternative") {
|
|
2256
|
+
const node = Object.assign(Object.assign({}, base), { parent });
|
|
2257
|
+
this._node = node;
|
|
2258
|
+
parent.elements.push(node);
|
|
2259
|
+
}
|
|
2260
|
+
else if (parent.type === "CharacterClass" &&
|
|
2261
|
+
parent.unicodeSets &&
|
|
2262
|
+
unicodeSets) {
|
|
2263
|
+
const node = Object.assign(Object.assign({}, base), { parent,
|
|
2264
|
+
unicodeSets });
|
|
2265
|
+
this._node = node;
|
|
2266
|
+
parent.elements.push(node);
|
|
2267
|
+
}
|
|
2268
|
+
else {
|
|
2269
|
+
throw new Error("UnknownError");
|
|
2270
|
+
}
|
|
1869
2271
|
}
|
|
1870
2272
|
onCharacterClassLeave(start, end) {
|
|
1871
2273
|
const node = this._node;
|
|
1872
2274
|
if (node.type !== "CharacterClass" ||
|
|
1873
|
-
node.parent.type !== "Alternative"
|
|
2275
|
+
(node.parent.type !== "Alternative" &&
|
|
2276
|
+
node.parent.type !== "CharacterClass") ||
|
|
2277
|
+
(this._expressionBuffer && node.elements.length > 0)) {
|
|
1874
2278
|
throw new Error("UnknownError");
|
|
1875
2279
|
}
|
|
2280
|
+
const parent = node.parent;
|
|
1876
2281
|
node.end = end;
|
|
1877
2282
|
node.raw = this.source.slice(start, end);
|
|
1878
|
-
this._node =
|
|
2283
|
+
this._node = parent;
|
|
2284
|
+
const expression = this._expressionBuffer;
|
|
2285
|
+
this._expressionBuffer = null;
|
|
2286
|
+
if (!expression) {
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
const newNode = {
|
|
2290
|
+
type: "ExpressionCharacterClass",
|
|
2291
|
+
parent,
|
|
2292
|
+
start: node.start,
|
|
2293
|
+
end: node.end,
|
|
2294
|
+
raw: node.raw,
|
|
2295
|
+
negate: node.negate,
|
|
2296
|
+
expression,
|
|
2297
|
+
};
|
|
2298
|
+
expression.parent = newNode;
|
|
2299
|
+
if (node !== parent.elements.pop()) {
|
|
2300
|
+
throw new Error("UnknownError");
|
|
2301
|
+
}
|
|
2302
|
+
parent.elements.push(newNode);
|
|
1879
2303
|
}
|
|
1880
2304
|
onCharacterClassRange(start, end) {
|
|
1881
2305
|
const parent = this._node;
|
|
@@ -1884,15 +2308,19 @@ class RegExpParserState {
|
|
|
1884
2308
|
}
|
|
1885
2309
|
const elements = parent.elements;
|
|
1886
2310
|
const max = elements.pop();
|
|
1887
|
-
|
|
2311
|
+
if (!max || max.type !== "Character") {
|
|
2312
|
+
throw new Error("UnknownError");
|
|
2313
|
+
}
|
|
2314
|
+
if (!parent.unicodeSets) {
|
|
2315
|
+
const hyphen = elements.pop();
|
|
2316
|
+
if (!hyphen ||
|
|
2317
|
+
hyphen.type !== "Character" ||
|
|
2318
|
+
hyphen.value !== HYPHEN_MINUS) {
|
|
2319
|
+
throw new Error("UnknownError");
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
1888
2322
|
const min = elements.pop();
|
|
1889
|
-
if (!min ||
|
|
1890
|
-
!max ||
|
|
1891
|
-
!hyphen ||
|
|
1892
|
-
min.type !== "Character" ||
|
|
1893
|
-
max.type !== "Character" ||
|
|
1894
|
-
hyphen.type !== "Character" ||
|
|
1895
|
-
hyphen.value !== HYPHEN_MINUS) {
|
|
2323
|
+
if (!min || min.type !== "Character") {
|
|
1896
2324
|
throw new Error("UnknownError");
|
|
1897
2325
|
}
|
|
1898
2326
|
const node = {
|
|
@@ -1908,6 +2336,111 @@ class RegExpParserState {
|
|
|
1908
2336
|
max.parent = node;
|
|
1909
2337
|
elements.push(node);
|
|
1910
2338
|
}
|
|
2339
|
+
onClassIntersection(start, end) {
|
|
2340
|
+
var _a;
|
|
2341
|
+
const parent = this._node;
|
|
2342
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2343
|
+
throw new Error("UnknownError");
|
|
2344
|
+
}
|
|
2345
|
+
const right = parent.elements.pop();
|
|
2346
|
+
const left = (_a = this._expressionBuffer) !== null && _a !== void 0 ? _a : parent.elements.pop();
|
|
2347
|
+
if (!left ||
|
|
2348
|
+
!right ||
|
|
2349
|
+
left.type === "ClassSubtraction" ||
|
|
2350
|
+
(left.type !== "ClassIntersection" && !isClassSetOperand(left)) ||
|
|
2351
|
+
!isClassSetOperand(right)) {
|
|
2352
|
+
throw new Error("UnknownError");
|
|
2353
|
+
}
|
|
2354
|
+
const node = {
|
|
2355
|
+
type: "ClassIntersection",
|
|
2356
|
+
parent: parent,
|
|
2357
|
+
start,
|
|
2358
|
+
end,
|
|
2359
|
+
raw: this.source.slice(start, end),
|
|
2360
|
+
left,
|
|
2361
|
+
right,
|
|
2362
|
+
};
|
|
2363
|
+
left.parent = node;
|
|
2364
|
+
right.parent = node;
|
|
2365
|
+
this._expressionBuffer = node;
|
|
2366
|
+
}
|
|
2367
|
+
onClassSubtraction(start, end) {
|
|
2368
|
+
var _a;
|
|
2369
|
+
const parent = this._node;
|
|
2370
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2371
|
+
throw new Error("UnknownError");
|
|
2372
|
+
}
|
|
2373
|
+
const right = parent.elements.pop();
|
|
2374
|
+
const left = (_a = this._expressionBuffer) !== null && _a !== void 0 ? _a : parent.elements.pop();
|
|
2375
|
+
if (!left ||
|
|
2376
|
+
!right ||
|
|
2377
|
+
left.type === "ClassIntersection" ||
|
|
2378
|
+
(left.type !== "ClassSubtraction" && !isClassSetOperand(left)) ||
|
|
2379
|
+
!isClassSetOperand(right)) {
|
|
2380
|
+
throw new Error("UnknownError");
|
|
2381
|
+
}
|
|
2382
|
+
const node = {
|
|
2383
|
+
type: "ClassSubtraction",
|
|
2384
|
+
parent: parent,
|
|
2385
|
+
start,
|
|
2386
|
+
end,
|
|
2387
|
+
raw: this.source.slice(start, end),
|
|
2388
|
+
left,
|
|
2389
|
+
right,
|
|
2390
|
+
};
|
|
2391
|
+
left.parent = node;
|
|
2392
|
+
right.parent = node;
|
|
2393
|
+
this._expressionBuffer = node;
|
|
2394
|
+
}
|
|
2395
|
+
onClassStringDisjunctionEnter(start) {
|
|
2396
|
+
const parent = this._node;
|
|
2397
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2398
|
+
throw new Error("UnknownError");
|
|
2399
|
+
}
|
|
2400
|
+
this._node = {
|
|
2401
|
+
type: "ClassStringDisjunction",
|
|
2402
|
+
parent,
|
|
2403
|
+
start,
|
|
2404
|
+
end: start,
|
|
2405
|
+
raw: "",
|
|
2406
|
+
alternatives: [],
|
|
2407
|
+
};
|
|
2408
|
+
parent.elements.push(this._node);
|
|
2409
|
+
}
|
|
2410
|
+
onClassStringDisjunctionLeave(start, end) {
|
|
2411
|
+
const node = this._node;
|
|
2412
|
+
if (node.type !== "ClassStringDisjunction" ||
|
|
2413
|
+
node.parent.type !== "CharacterClass") {
|
|
2414
|
+
throw new Error("UnknownError");
|
|
2415
|
+
}
|
|
2416
|
+
node.end = end;
|
|
2417
|
+
node.raw = this.source.slice(start, end);
|
|
2418
|
+
this._node = node.parent;
|
|
2419
|
+
}
|
|
2420
|
+
onStringAlternativeEnter(start) {
|
|
2421
|
+
const parent = this._node;
|
|
2422
|
+
if (parent.type !== "ClassStringDisjunction") {
|
|
2423
|
+
throw new Error("UnknownError");
|
|
2424
|
+
}
|
|
2425
|
+
this._node = {
|
|
2426
|
+
type: "StringAlternative",
|
|
2427
|
+
parent,
|
|
2428
|
+
start,
|
|
2429
|
+
end: start,
|
|
2430
|
+
raw: "",
|
|
2431
|
+
elements: [],
|
|
2432
|
+
};
|
|
2433
|
+
parent.alternatives.push(this._node);
|
|
2434
|
+
}
|
|
2435
|
+
onStringAlternativeLeave(start, end) {
|
|
2436
|
+
const node = this._node;
|
|
2437
|
+
if (node.type !== "StringAlternative") {
|
|
2438
|
+
throw new Error("UnknownError");
|
|
2439
|
+
}
|
|
2440
|
+
node.end = end;
|
|
2441
|
+
node.raw = this.source.slice(start, end);
|
|
2442
|
+
this._node = node.parent;
|
|
2443
|
+
}
|
|
1911
2444
|
}
|
|
1912
2445
|
class RegExpParser {
|
|
1913
2446
|
constructor(options) {
|
|
@@ -1937,9 +2470,9 @@ class RegExpParser {
|
|
|
1937
2470
|
this._validator.validateFlags(source, start, end);
|
|
1938
2471
|
return this._state.flags;
|
|
1939
2472
|
}
|
|
1940
|
-
parsePattern(source, start = 0, end = source.length,
|
|
2473
|
+
parsePattern(source, start = 0, end = source.length, uFlagOrFlags = undefined) {
|
|
1941
2474
|
this._state.source = source;
|
|
1942
|
-
this._validator.validatePattern(source, start, end,
|
|
2475
|
+
this._validator.validatePattern(source, start, end, uFlagOrFlags);
|
|
1943
2476
|
return this._state.pattern;
|
|
1944
2477
|
}
|
|
1945
2478
|
}
|
|
@@ -1974,6 +2507,18 @@ class RegExpVisitor {
|
|
|
1974
2507
|
case "CharacterSet":
|
|
1975
2508
|
this.visitCharacterSet(node);
|
|
1976
2509
|
break;
|
|
2510
|
+
case "ClassIntersection":
|
|
2511
|
+
this.visitClassIntersection(node);
|
|
2512
|
+
break;
|
|
2513
|
+
case "ClassStringDisjunction":
|
|
2514
|
+
this.visitClassStringDisjunction(node);
|
|
2515
|
+
break;
|
|
2516
|
+
case "ClassSubtraction":
|
|
2517
|
+
this.visitClassSubtraction(node);
|
|
2518
|
+
break;
|
|
2519
|
+
case "ExpressionCharacterClass":
|
|
2520
|
+
this.visitExpressionCharacterClass(node);
|
|
2521
|
+
break;
|
|
1977
2522
|
case "Flags":
|
|
1978
2523
|
this.visitFlags(node);
|
|
1979
2524
|
break;
|
|
@@ -1989,6 +2534,9 @@ class RegExpVisitor {
|
|
|
1989
2534
|
case "RegExpLiteral":
|
|
1990
2535
|
this.visitRegExpLiteral(node);
|
|
1991
2536
|
break;
|
|
2537
|
+
case "StringAlternative":
|
|
2538
|
+
this.visitStringAlternative(node);
|
|
2539
|
+
break;
|
|
1992
2540
|
default:
|
|
1993
2541
|
throw new Error(`Unknown type: ${node.type}`);
|
|
1994
2542
|
}
|
|
@@ -2065,6 +2613,44 @@ class RegExpVisitor {
|
|
|
2065
2613
|
this._handlers.onCharacterSetLeave(node);
|
|
2066
2614
|
}
|
|
2067
2615
|
}
|
|
2616
|
+
visitClassIntersection(node) {
|
|
2617
|
+
if (this._handlers.onClassIntersectionEnter) {
|
|
2618
|
+
this._handlers.onClassIntersectionEnter(node);
|
|
2619
|
+
}
|
|
2620
|
+
this.visit(node.left);
|
|
2621
|
+
this.visit(node.right);
|
|
2622
|
+
if (this._handlers.onClassIntersectionLeave) {
|
|
2623
|
+
this._handlers.onClassIntersectionLeave(node);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
visitClassStringDisjunction(node) {
|
|
2627
|
+
if (this._handlers.onClassStringDisjunctionEnter) {
|
|
2628
|
+
this._handlers.onClassStringDisjunctionEnter(node);
|
|
2629
|
+
}
|
|
2630
|
+
node.alternatives.forEach(this.visit, this);
|
|
2631
|
+
if (this._handlers.onClassStringDisjunctionLeave) {
|
|
2632
|
+
this._handlers.onClassStringDisjunctionLeave(node);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
visitClassSubtraction(node) {
|
|
2636
|
+
if (this._handlers.onClassSubtractionEnter) {
|
|
2637
|
+
this._handlers.onClassSubtractionEnter(node);
|
|
2638
|
+
}
|
|
2639
|
+
this.visit(node.left);
|
|
2640
|
+
this.visit(node.right);
|
|
2641
|
+
if (this._handlers.onClassSubtractionLeave) {
|
|
2642
|
+
this._handlers.onClassSubtractionLeave(node);
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
visitExpressionCharacterClass(node) {
|
|
2646
|
+
if (this._handlers.onExpressionCharacterClassEnter) {
|
|
2647
|
+
this._handlers.onExpressionCharacterClassEnter(node);
|
|
2648
|
+
}
|
|
2649
|
+
this.visit(node.expression);
|
|
2650
|
+
if (this._handlers.onExpressionCharacterClassLeave) {
|
|
2651
|
+
this._handlers.onExpressionCharacterClassLeave(node);
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2068
2654
|
visitFlags(node) {
|
|
2069
2655
|
if (this._handlers.onFlagsEnter) {
|
|
2070
2656
|
this._handlers.onFlagsEnter(node);
|
|
@@ -2110,6 +2696,15 @@ class RegExpVisitor {
|
|
|
2110
2696
|
this._handlers.onRegExpLiteralLeave(node);
|
|
2111
2697
|
}
|
|
2112
2698
|
}
|
|
2699
|
+
visitStringAlternative(node) {
|
|
2700
|
+
if (this._handlers.onStringAlternativeEnter) {
|
|
2701
|
+
this._handlers.onStringAlternativeEnter(node);
|
|
2702
|
+
}
|
|
2703
|
+
node.elements.forEach(this.visit, this);
|
|
2704
|
+
if (this._handlers.onStringAlternativeLeave) {
|
|
2705
|
+
this._handlers.onStringAlternativeLeave(node);
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2113
2708
|
}
|
|
2114
2709
|
|
|
2115
2710
|
function parseRegExpLiteral(source, options) {
|