@eslint-community/regexpp 4.5.1 → 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 +709 -119
- package/index.js.map +1 -1
- package/index.mjs +709 -119
- package/index.mjs.map +1 -1
- package/package.json +5 -1
package/index.mjs
CHANGED
|
@@ -2,6 +2,8 @@ var ast = /*#__PURE__*/Object.freeze({
|
|
|
2
2
|
__proto__: null
|
|
3
3
|
});
|
|
4
4
|
|
|
5
|
+
const latestEcmaVersion = 2024;
|
|
6
|
+
|
|
5
7
|
let largeIdStartRanges = undefined;
|
|
6
8
|
let largeIdContinueRanges = undefined;
|
|
7
9
|
function isIdStart(cp) {
|
|
@@ -138,7 +140,10 @@ const LINE_TABULATION = 0x0b;
|
|
|
138
140
|
const FORM_FEED = 0x0c;
|
|
139
141
|
const CARRIAGE_RETURN = 0x0d;
|
|
140
142
|
const EXCLAMATION_MARK = 0x21;
|
|
143
|
+
const NUMBER_SIGN = 0x23;
|
|
141
144
|
const DOLLAR_SIGN = 0x24;
|
|
145
|
+
const PERCENT_SIGN = 0x25;
|
|
146
|
+
const AMPERSAND = 0x26;
|
|
142
147
|
const LEFT_PARENTHESIS = 0x28;
|
|
143
148
|
const RIGHT_PARENTHESIS = 0x29;
|
|
144
149
|
const ASTERISK = 0x2a;
|
|
@@ -152,10 +157,12 @@ const DIGIT_ONE = 0x31;
|
|
|
152
157
|
const DIGIT_SEVEN = 0x37;
|
|
153
158
|
const DIGIT_NINE = 0x39;
|
|
154
159
|
const COLON = 0x3a;
|
|
160
|
+
const SEMICOLON = 0x3b;
|
|
155
161
|
const LESS_THAN_SIGN = 0x3c;
|
|
156
162
|
const EQUALS_SIGN = 0x3d;
|
|
157
163
|
const GREATER_THAN_SIGN = 0x3e;
|
|
158
164
|
const QUESTION_MARK = 0x3f;
|
|
165
|
+
const COMMERCIAL_AT = 0x40;
|
|
159
166
|
const LATIN_CAPITAL_LETTER_A = 0x41;
|
|
160
167
|
const LATIN_CAPITAL_LETTER_B = 0x42;
|
|
161
168
|
const LATIN_CAPITAL_LETTER_D = 0x44;
|
|
@@ -176,6 +183,7 @@ const LATIN_SMALL_LETTER_K = 0x6b;
|
|
|
176
183
|
const LATIN_SMALL_LETTER_M = 0x6d;
|
|
177
184
|
const LATIN_SMALL_LETTER_N = 0x6e;
|
|
178
185
|
const LATIN_SMALL_LETTER_P = 0x70;
|
|
186
|
+
const LATIN_SMALL_LETTER_Q = 0x71;
|
|
179
187
|
const LATIN_SMALL_LETTER_R = 0x72;
|
|
180
188
|
const LATIN_SMALL_LETTER_S = 0x73;
|
|
181
189
|
const LATIN_SMALL_LETTER_T = 0x74;
|
|
@@ -189,9 +197,11 @@ const LEFT_SQUARE_BRACKET = 0x5b;
|
|
|
189
197
|
const REVERSE_SOLIDUS = 0x5c;
|
|
190
198
|
const RIGHT_SQUARE_BRACKET = 0x5d;
|
|
191
199
|
const CIRCUMFLEX_ACCENT = 0x5e;
|
|
200
|
+
const GRAVE_ACCENT = 0x60;
|
|
192
201
|
const LEFT_CURLY_BRACKET = 0x7b;
|
|
193
202
|
const VERTICAL_LINE = 0x7c;
|
|
194
203
|
const RIGHT_CURLY_BRACKET = 0x7d;
|
|
204
|
+
const TILDE = 0x7e;
|
|
195
205
|
const ZERO_WIDTH_NON_JOINER = 0x200c;
|
|
196
206
|
const ZERO_WIDTH_JOINER = 0x200d;
|
|
197
207
|
const LINE_SEPARATOR = 0x2028;
|
|
@@ -358,29 +368,102 @@ class RegExpSyntaxError extends SyntaxError {
|
|
|
358
368
|
}
|
|
359
369
|
}
|
|
360
370
|
|
|
371
|
+
const binPropertyOfStringSets = new Set([
|
|
372
|
+
"Basic_Emoji",
|
|
373
|
+
"Emoji_Keycap_Sequence",
|
|
374
|
+
"RGI_Emoji_Modifier_Sequence",
|
|
375
|
+
"RGI_Emoji_Flag_Sequence",
|
|
376
|
+
"RGI_Emoji_Tag_Sequence",
|
|
377
|
+
"RGI_Emoji_ZWJ_Sequence",
|
|
378
|
+
"RGI_Emoji",
|
|
379
|
+
]);
|
|
380
|
+
function isValidLoneUnicodePropertyOfString(version, value) {
|
|
381
|
+
return version >= 2024 && binPropertyOfStringSets.has(value);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const SYNTAX_CHARACTER = new Set([
|
|
385
|
+
CIRCUMFLEX_ACCENT,
|
|
386
|
+
DOLLAR_SIGN,
|
|
387
|
+
REVERSE_SOLIDUS,
|
|
388
|
+
FULL_STOP,
|
|
389
|
+
ASTERISK,
|
|
390
|
+
PLUS_SIGN,
|
|
391
|
+
QUESTION_MARK,
|
|
392
|
+
LEFT_PARENTHESIS,
|
|
393
|
+
RIGHT_PARENTHESIS,
|
|
394
|
+
LEFT_SQUARE_BRACKET,
|
|
395
|
+
RIGHT_SQUARE_BRACKET,
|
|
396
|
+
LEFT_CURLY_BRACKET,
|
|
397
|
+
RIGHT_CURLY_BRACKET,
|
|
398
|
+
VERTICAL_LINE,
|
|
399
|
+
]);
|
|
400
|
+
const CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR_CHARACTER = new Set([
|
|
401
|
+
AMPERSAND,
|
|
402
|
+
EXCLAMATION_MARK,
|
|
403
|
+
NUMBER_SIGN,
|
|
404
|
+
DOLLAR_SIGN,
|
|
405
|
+
PERCENT_SIGN,
|
|
406
|
+
ASTERISK,
|
|
407
|
+
PLUS_SIGN,
|
|
408
|
+
COMMA,
|
|
409
|
+
FULL_STOP,
|
|
410
|
+
COLON,
|
|
411
|
+
SEMICOLON,
|
|
412
|
+
LESS_THAN_SIGN,
|
|
413
|
+
EQUALS_SIGN,
|
|
414
|
+
GREATER_THAN_SIGN,
|
|
415
|
+
QUESTION_MARK,
|
|
416
|
+
COMMERCIAL_AT,
|
|
417
|
+
CIRCUMFLEX_ACCENT,
|
|
418
|
+
GRAVE_ACCENT,
|
|
419
|
+
TILDE,
|
|
420
|
+
]);
|
|
421
|
+
const CLASS_SET_SYNTAX_CHARACTER = new Set([
|
|
422
|
+
LEFT_PARENTHESIS,
|
|
423
|
+
RIGHT_PARENTHESIS,
|
|
424
|
+
LEFT_SQUARE_BRACKET,
|
|
425
|
+
RIGHT_SQUARE_BRACKET,
|
|
426
|
+
LEFT_CURLY_BRACKET,
|
|
427
|
+
RIGHT_CURLY_BRACKET,
|
|
428
|
+
SOLIDUS,
|
|
429
|
+
HYPHEN_MINUS,
|
|
430
|
+
REVERSE_SOLIDUS,
|
|
431
|
+
VERTICAL_LINE,
|
|
432
|
+
]);
|
|
433
|
+
const CLASS_SET_RESERVED_PUNCTUATOR = new Set([
|
|
434
|
+
AMPERSAND,
|
|
435
|
+
HYPHEN_MINUS,
|
|
436
|
+
EXCLAMATION_MARK,
|
|
437
|
+
NUMBER_SIGN,
|
|
438
|
+
PERCENT_SIGN,
|
|
439
|
+
COMMA,
|
|
440
|
+
COLON,
|
|
441
|
+
SEMICOLON,
|
|
442
|
+
LESS_THAN_SIGN,
|
|
443
|
+
EQUALS_SIGN,
|
|
444
|
+
GREATER_THAN_SIGN,
|
|
445
|
+
COMMERCIAL_AT,
|
|
446
|
+
GRAVE_ACCENT,
|
|
447
|
+
TILDE,
|
|
448
|
+
]);
|
|
361
449
|
function isSyntaxCharacter(cp) {
|
|
362
|
-
return (cp
|
|
363
|
-
cp === DOLLAR_SIGN ||
|
|
364
|
-
cp === REVERSE_SOLIDUS ||
|
|
365
|
-
cp === FULL_STOP ||
|
|
366
|
-
cp === ASTERISK ||
|
|
367
|
-
cp === PLUS_SIGN ||
|
|
368
|
-
cp === QUESTION_MARK ||
|
|
369
|
-
cp === LEFT_PARENTHESIS ||
|
|
370
|
-
cp === RIGHT_PARENTHESIS ||
|
|
371
|
-
cp === LEFT_SQUARE_BRACKET ||
|
|
372
|
-
cp === RIGHT_SQUARE_BRACKET ||
|
|
373
|
-
cp === LEFT_CURLY_BRACKET ||
|
|
374
|
-
cp === RIGHT_CURLY_BRACKET ||
|
|
375
|
-
cp === VERTICAL_LINE);
|
|
450
|
+
return SYNTAX_CHARACTER.has(cp);
|
|
376
451
|
}
|
|
377
|
-
function
|
|
452
|
+
function isClassSetReservedDoublePunctuatorCharacter(cp) {
|
|
453
|
+
return CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR_CHARACTER.has(cp);
|
|
454
|
+
}
|
|
455
|
+
function isClassSetSyntaxCharacter(cp) {
|
|
456
|
+
return CLASS_SET_SYNTAX_CHARACTER.has(cp);
|
|
457
|
+
}
|
|
458
|
+
function isClassSetReservedPunctuator(cp) {
|
|
459
|
+
return CLASS_SET_RESERVED_PUNCTUATOR.has(cp);
|
|
460
|
+
}
|
|
461
|
+
function isIdentifierStartChar(cp) {
|
|
378
462
|
return isIdStart(cp) || cp === DOLLAR_SIGN || cp === LOW_LINE;
|
|
379
463
|
}
|
|
380
|
-
function
|
|
464
|
+
function isIdentifierPartChar(cp) {
|
|
381
465
|
return (isIdContinue(cp) ||
|
|
382
466
|
cp === DOLLAR_SIGN ||
|
|
383
|
-
cp === LOW_LINE ||
|
|
384
467
|
cp === ZERO_WIDTH_NON_JOINER ||
|
|
385
468
|
cp === ZERO_WIDTH_JOINER);
|
|
386
469
|
}
|
|
@@ -393,14 +476,15 @@ function isUnicodePropertyValueCharacter(cp) {
|
|
|
393
476
|
class RegExpValidator {
|
|
394
477
|
constructor(options) {
|
|
395
478
|
this._reader = new Reader();
|
|
396
|
-
this.
|
|
479
|
+
this._unicodeMode = false;
|
|
480
|
+
this._unicodeSetsMode = false;
|
|
397
481
|
this._nFlag = false;
|
|
398
482
|
this._lastIntValue = 0;
|
|
399
|
-
this.
|
|
400
|
-
|
|
483
|
+
this._lastRange = {
|
|
484
|
+
min: 0,
|
|
485
|
+
max: Number.POSITIVE_INFINITY,
|
|
486
|
+
};
|
|
401
487
|
this._lastStrValue = "";
|
|
402
|
-
this._lastKeyValue = "";
|
|
403
|
-
this._lastValValue = "";
|
|
404
488
|
this._lastAssertionIsQuantifiable = false;
|
|
405
489
|
this._numCapturingParens = 0;
|
|
406
490
|
this._groupNames = new Set();
|
|
@@ -408,14 +492,18 @@ class RegExpValidator {
|
|
|
408
492
|
this._options = options !== null && options !== void 0 ? options : {};
|
|
409
493
|
}
|
|
410
494
|
validateLiteral(source, start = 0, end = source.length) {
|
|
411
|
-
this.
|
|
495
|
+
this._unicodeSetsMode = this._unicodeMode = this._nFlag = false;
|
|
412
496
|
this.reset(source, start, end);
|
|
413
497
|
this.onLiteralEnter(start);
|
|
414
498
|
if (this.eat(SOLIDUS) && this.eatRegExpBody() && this.eat(SOLIDUS)) {
|
|
415
499
|
const flagStart = this.index;
|
|
416
|
-
const
|
|
500
|
+
const unicode = source.includes("u", flagStart);
|
|
501
|
+
const unicodeSets = source.includes("v", flagStart);
|
|
417
502
|
this.validateFlags(source, flagStart, end);
|
|
418
|
-
this.validatePattern(source, start + 1, flagStart - 1,
|
|
503
|
+
this.validatePattern(source, start + 1, flagStart - 1, {
|
|
504
|
+
unicode,
|
|
505
|
+
unicodeSets,
|
|
506
|
+
});
|
|
419
507
|
}
|
|
420
508
|
else if (start >= end) {
|
|
421
509
|
this.raise("Empty");
|
|
@@ -435,6 +523,7 @@ class RegExpValidator {
|
|
|
435
523
|
let unicode = false;
|
|
436
524
|
let dotAll = false;
|
|
437
525
|
let hasIndices = false;
|
|
526
|
+
let unicodeSets = false;
|
|
438
527
|
for (let i = start; i < end; ++i) {
|
|
439
528
|
const flag = source.charCodeAt(i);
|
|
440
529
|
if (existingFlags.has(flag)) {
|
|
@@ -466,6 +555,10 @@ class RegExpValidator {
|
|
|
466
555
|
this.ecmaVersion >= 2022) {
|
|
467
556
|
hasIndices = true;
|
|
468
557
|
}
|
|
558
|
+
else if (flag === LATIN_SMALL_LETTER_V &&
|
|
559
|
+
this.ecmaVersion >= 2024) {
|
|
560
|
+
unicodeSets = true;
|
|
561
|
+
}
|
|
469
562
|
else {
|
|
470
563
|
this.raise(`Invalid flag '${source[i]}'`);
|
|
471
564
|
}
|
|
@@ -478,13 +571,14 @@ class RegExpValidator {
|
|
|
478
571
|
sticky,
|
|
479
572
|
dotAll,
|
|
480
573
|
hasIndices,
|
|
574
|
+
unicodeSets,
|
|
481
575
|
});
|
|
482
576
|
}
|
|
483
|
-
validatePattern(source, start = 0, end = source.length,
|
|
484
|
-
|
|
485
|
-
this.
|
|
486
|
-
|
|
487
|
-
|
|
577
|
+
validatePattern(source, start = 0, end = source.length, uFlagOrFlags = undefined) {
|
|
578
|
+
const mode = this._parseFlagsOptionToMode(uFlagOrFlags);
|
|
579
|
+
this._unicodeMode = mode.unicodeMode;
|
|
580
|
+
this._nFlag = mode.nFlag;
|
|
581
|
+
this._unicodeSetsMode = mode.unicodeSetsMode;
|
|
488
582
|
this.reset(source, start, end);
|
|
489
583
|
this.consumePattern();
|
|
490
584
|
if (!this._nFlag &&
|
|
@@ -495,12 +589,36 @@ class RegExpValidator {
|
|
|
495
589
|
this.consumePattern();
|
|
496
590
|
}
|
|
497
591
|
}
|
|
592
|
+
_parseFlagsOptionToMode(uFlagOrFlags = undefined) {
|
|
593
|
+
let unicode = false;
|
|
594
|
+
let unicodeSets = false;
|
|
595
|
+
if (uFlagOrFlags && this.ecmaVersion >= 2015) {
|
|
596
|
+
if (typeof uFlagOrFlags === "object") {
|
|
597
|
+
unicode = Boolean(uFlagOrFlags.unicode);
|
|
598
|
+
if (this.ecmaVersion >= 2024) {
|
|
599
|
+
unicodeSets = Boolean(uFlagOrFlags.unicodeSets);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
unicode = uFlagOrFlags;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (unicode && unicodeSets) {
|
|
607
|
+
this.raise("Invalid regular expression flags");
|
|
608
|
+
}
|
|
609
|
+
const unicodeMode = unicode || unicodeSets;
|
|
610
|
+
const nFlag = (unicode && this.ecmaVersion >= 2018) ||
|
|
611
|
+
unicodeSets ||
|
|
612
|
+
Boolean(this._options.strict && this.ecmaVersion >= 2023);
|
|
613
|
+
const unicodeSetsMode = unicodeSets;
|
|
614
|
+
return { unicodeMode, nFlag, unicodeSetsMode };
|
|
615
|
+
}
|
|
498
616
|
get strict() {
|
|
499
|
-
return Boolean(this._options.strict) || this.
|
|
617
|
+
return Boolean(this._options.strict) || this._unicodeMode;
|
|
500
618
|
}
|
|
501
619
|
get ecmaVersion() {
|
|
502
620
|
var _a;
|
|
503
|
-
return (_a = this._options.ecmaVersion) !== null && _a !== void 0 ? _a :
|
|
621
|
+
return (_a = this._options.ecmaVersion) !== null && _a !== void 0 ? _a : latestEcmaVersion;
|
|
504
622
|
}
|
|
505
623
|
onLiteralEnter(start) {
|
|
506
624
|
if (this._options.onLiteralEnter) {
|
|
@@ -605,9 +723,9 @@ class RegExpValidator {
|
|
|
605
723
|
this._options.onEscapeCharacterSet(start, end, kind, negate);
|
|
606
724
|
}
|
|
607
725
|
}
|
|
608
|
-
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
|
|
726
|
+
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings) {
|
|
609
727
|
if (this._options.onUnicodePropertyCharacterSet) {
|
|
610
|
-
this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate);
|
|
728
|
+
this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings);
|
|
611
729
|
}
|
|
612
730
|
}
|
|
613
731
|
onCharacter(start, end, value) {
|
|
@@ -620,9 +738,9 @@ class RegExpValidator {
|
|
|
620
738
|
this._options.onBackreference(start, end, ref);
|
|
621
739
|
}
|
|
622
740
|
}
|
|
623
|
-
onCharacterClassEnter(start, negate) {
|
|
741
|
+
onCharacterClassEnter(start, negate, unicodeSets) {
|
|
624
742
|
if (this._options.onCharacterClassEnter) {
|
|
625
|
-
this._options.onCharacterClassEnter(start, negate);
|
|
743
|
+
this._options.onCharacterClassEnter(start, negate, unicodeSets);
|
|
626
744
|
}
|
|
627
745
|
}
|
|
628
746
|
onCharacterClassLeave(start, end, negate) {
|
|
@@ -635,6 +753,36 @@ class RegExpValidator {
|
|
|
635
753
|
this._options.onCharacterClassRange(start, end, min, max);
|
|
636
754
|
}
|
|
637
755
|
}
|
|
756
|
+
onClassIntersection(start, end) {
|
|
757
|
+
if (this._options.onClassIntersection) {
|
|
758
|
+
this._options.onClassIntersection(start, end);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
onClassSubtraction(start, end) {
|
|
762
|
+
if (this._options.onClassSubtraction) {
|
|
763
|
+
this._options.onClassSubtraction(start, end);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
onClassStringDisjunctionEnter(start) {
|
|
767
|
+
if (this._options.onClassStringDisjunctionEnter) {
|
|
768
|
+
this._options.onClassStringDisjunctionEnter(start);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
onClassStringDisjunctionLeave(start, end) {
|
|
772
|
+
if (this._options.onClassStringDisjunctionLeave) {
|
|
773
|
+
this._options.onClassStringDisjunctionLeave(start, end);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
onStringAlternativeEnter(start, index) {
|
|
777
|
+
if (this._options.onStringAlternativeEnter) {
|
|
778
|
+
this._options.onStringAlternativeEnter(start, index);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
onStringAlternativeLeave(start, end, index) {
|
|
782
|
+
if (this._options.onStringAlternativeLeave) {
|
|
783
|
+
this._options.onStringAlternativeLeave(start, end, index);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
638
786
|
get source() {
|
|
639
787
|
return this._reader.source;
|
|
640
788
|
}
|
|
@@ -654,7 +802,7 @@ class RegExpValidator {
|
|
|
654
802
|
return this._reader.nextCodePoint3;
|
|
655
803
|
}
|
|
656
804
|
reset(source, start, end) {
|
|
657
|
-
this._reader.reset(source, start, end, this.
|
|
805
|
+
this._reader.reset(source, start, end, this._unicodeMode);
|
|
658
806
|
}
|
|
659
807
|
rewind(index) {
|
|
660
808
|
this._reader.rewind(index);
|
|
@@ -672,7 +820,7 @@ class RegExpValidator {
|
|
|
672
820
|
return this._reader.eat3(cp1, cp2, cp3);
|
|
673
821
|
}
|
|
674
822
|
raise(message) {
|
|
675
|
-
throw new RegExpSyntaxError(this.source, this.
|
|
823
|
+
throw new RegExpSyntaxError(this.source, this._unicodeMode, this.index, message);
|
|
676
824
|
}
|
|
677
825
|
eatRegExpBody() {
|
|
678
826
|
const start = this.index;
|
|
@@ -787,7 +935,7 @@ class RegExpValidator {
|
|
|
787
935
|
this.onAlternativeLeave(start, this.index, i);
|
|
788
936
|
}
|
|
789
937
|
consumeTerm() {
|
|
790
|
-
if (this.
|
|
938
|
+
if (this._unicodeMode || this.strict) {
|
|
791
939
|
return (this.consumeAssertion() ||
|
|
792
940
|
(this.consumeAtom() && this.consumeOptionalQuantifier()));
|
|
793
941
|
}
|
|
@@ -856,8 +1004,7 @@ class RegExpValidator {
|
|
|
856
1004
|
max = 1;
|
|
857
1005
|
}
|
|
858
1006
|
else if (this.eatBracedQuantifier(noConsume)) {
|
|
859
|
-
min = this.
|
|
860
|
-
max = this._lastMaxValue;
|
|
1007
|
+
({ min, max } = this._lastRange);
|
|
861
1008
|
}
|
|
862
1009
|
else {
|
|
863
1010
|
return false;
|
|
@@ -871,23 +1018,23 @@ class RegExpValidator {
|
|
|
871
1018
|
eatBracedQuantifier(noError) {
|
|
872
1019
|
const start = this.index;
|
|
873
1020
|
if (this.eat(LEFT_CURLY_BRACKET)) {
|
|
874
|
-
this._lastMinValue = 0;
|
|
875
|
-
this._lastMaxValue = Number.POSITIVE_INFINITY;
|
|
876
1021
|
if (this.eatDecimalDigits()) {
|
|
877
|
-
|
|
1022
|
+
const min = this._lastIntValue;
|
|
1023
|
+
let max = min;
|
|
878
1024
|
if (this.eat(COMMA)) {
|
|
879
|
-
|
|
1025
|
+
max = this.eatDecimalDigits()
|
|
880
1026
|
? this._lastIntValue
|
|
881
1027
|
: Number.POSITIVE_INFINITY;
|
|
882
1028
|
}
|
|
883
1029
|
if (this.eat(RIGHT_CURLY_BRACKET)) {
|
|
884
|
-
if (!noError &&
|
|
1030
|
+
if (!noError && max < min) {
|
|
885
1031
|
this.raise("numbers out of order in {} quantifier");
|
|
886
1032
|
}
|
|
1033
|
+
this._lastRange = { min, max };
|
|
887
1034
|
return true;
|
|
888
1035
|
}
|
|
889
1036
|
}
|
|
890
|
-
if (!noError && (this.
|
|
1037
|
+
if (!noError && (this._unicodeMode || this.strict)) {
|
|
891
1038
|
this.raise("Incomplete quantifier");
|
|
892
1039
|
}
|
|
893
1040
|
this.rewind(start);
|
|
@@ -898,7 +1045,7 @@ class RegExpValidator {
|
|
|
898
1045
|
return (this.consumePatternCharacter() ||
|
|
899
1046
|
this.consumeDot() ||
|
|
900
1047
|
this.consumeReverseSolidusAtomEscape() ||
|
|
901
|
-
this.consumeCharacterClass() ||
|
|
1048
|
+
Boolean(this.consumeCharacterClass()) ||
|
|
902
1049
|
this.consumeUncapturingGroup() ||
|
|
903
1050
|
this.consumeCapturingGroup());
|
|
904
1051
|
}
|
|
@@ -958,7 +1105,7 @@ class RegExpValidator {
|
|
|
958
1105
|
return (this.consumeDot() ||
|
|
959
1106
|
this.consumeReverseSolidusAtomEscape() ||
|
|
960
1107
|
this.consumeReverseSolidusFollowedByC() ||
|
|
961
|
-
this.consumeCharacterClass() ||
|
|
1108
|
+
Boolean(this.consumeCharacterClass()) ||
|
|
962
1109
|
this.consumeUncapturingGroup() ||
|
|
963
1110
|
this.consumeCapturingGroup() ||
|
|
964
1111
|
this.consumeInvalidBracedQuantifier() ||
|
|
@@ -1032,7 +1179,7 @@ class RegExpValidator {
|
|
|
1032
1179
|
(this._nFlag && this.consumeKGroupName())) {
|
|
1033
1180
|
return true;
|
|
1034
1181
|
}
|
|
1035
|
-
if (this.strict || this.
|
|
1182
|
+
if (this.strict || this._unicodeMode) {
|
|
1036
1183
|
this.raise("Invalid escape");
|
|
1037
1184
|
}
|
|
1038
1185
|
return false;
|
|
@@ -1045,7 +1192,7 @@ class RegExpValidator {
|
|
|
1045
1192
|
this.onBackreference(start - 1, this.index, n);
|
|
1046
1193
|
return true;
|
|
1047
1194
|
}
|
|
1048
|
-
if (this.strict || this.
|
|
1195
|
+
if (this.strict || this._unicodeMode) {
|
|
1049
1196
|
this.raise("Invalid escape");
|
|
1050
1197
|
}
|
|
1051
1198
|
this.rewind(start);
|
|
@@ -1053,52 +1200,57 @@ class RegExpValidator {
|
|
|
1053
1200
|
return false;
|
|
1054
1201
|
}
|
|
1055
1202
|
consumeCharacterClassEscape() {
|
|
1203
|
+
var _a;
|
|
1056
1204
|
const start = this.index;
|
|
1057
1205
|
if (this.eat(LATIN_SMALL_LETTER_D)) {
|
|
1058
1206
|
this._lastIntValue = -1;
|
|
1059
1207
|
this.onEscapeCharacterSet(start - 1, this.index, "digit", false);
|
|
1060
|
-
return
|
|
1208
|
+
return {};
|
|
1061
1209
|
}
|
|
1062
1210
|
if (this.eat(LATIN_CAPITAL_LETTER_D)) {
|
|
1063
1211
|
this._lastIntValue = -1;
|
|
1064
1212
|
this.onEscapeCharacterSet(start - 1, this.index, "digit", true);
|
|
1065
|
-
return
|
|
1213
|
+
return {};
|
|
1066
1214
|
}
|
|
1067
1215
|
if (this.eat(LATIN_SMALL_LETTER_S)) {
|
|
1068
1216
|
this._lastIntValue = -1;
|
|
1069
1217
|
this.onEscapeCharacterSet(start - 1, this.index, "space", false);
|
|
1070
|
-
return
|
|
1218
|
+
return {};
|
|
1071
1219
|
}
|
|
1072
1220
|
if (this.eat(LATIN_CAPITAL_LETTER_S)) {
|
|
1073
1221
|
this._lastIntValue = -1;
|
|
1074
1222
|
this.onEscapeCharacterSet(start - 1, this.index, "space", true);
|
|
1075
|
-
return
|
|
1223
|
+
return {};
|
|
1076
1224
|
}
|
|
1077
1225
|
if (this.eat(LATIN_SMALL_LETTER_W)) {
|
|
1078
1226
|
this._lastIntValue = -1;
|
|
1079
1227
|
this.onEscapeCharacterSet(start - 1, this.index, "word", false);
|
|
1080
|
-
return
|
|
1228
|
+
return {};
|
|
1081
1229
|
}
|
|
1082
1230
|
if (this.eat(LATIN_CAPITAL_LETTER_W)) {
|
|
1083
1231
|
this._lastIntValue = -1;
|
|
1084
1232
|
this.onEscapeCharacterSet(start - 1, this.index, "word", true);
|
|
1085
|
-
return
|
|
1233
|
+
return {};
|
|
1086
1234
|
}
|
|
1087
1235
|
let negate = false;
|
|
1088
|
-
if (this.
|
|
1236
|
+
if (this._unicodeMode &&
|
|
1089
1237
|
this.ecmaVersion >= 2018 &&
|
|
1090
1238
|
(this.eat(LATIN_SMALL_LETTER_P) ||
|
|
1091
1239
|
(negate = this.eat(LATIN_CAPITAL_LETTER_P)))) {
|
|
1092
1240
|
this._lastIntValue = -1;
|
|
1241
|
+
let result = null;
|
|
1093
1242
|
if (this.eat(LEFT_CURLY_BRACKET) &&
|
|
1094
|
-
this.eatUnicodePropertyValueExpression() &&
|
|
1243
|
+
(result = this.eatUnicodePropertyValueExpression()) &&
|
|
1095
1244
|
this.eat(RIGHT_CURLY_BRACKET)) {
|
|
1096
|
-
|
|
1097
|
-
|
|
1245
|
+
if (negate && result.strings) {
|
|
1246
|
+
this.raise("Invalid property name");
|
|
1247
|
+
}
|
|
1248
|
+
this.onUnicodePropertyCharacterSet(start - 1, this.index, "property", result.key, result.value, negate, (_a = result.strings) !== null && _a !== void 0 ? _a : false);
|
|
1249
|
+
return { mayContainStrings: result.strings };
|
|
1098
1250
|
}
|
|
1099
1251
|
this.raise("Invalid property name");
|
|
1100
1252
|
}
|
|
1101
|
-
return
|
|
1253
|
+
return null;
|
|
1102
1254
|
}
|
|
1103
1255
|
consumeCharacterEscape() {
|
|
1104
1256
|
const start = this.index;
|
|
@@ -1108,7 +1260,7 @@ class RegExpValidator {
|
|
|
1108
1260
|
this.eatHexEscapeSequence() ||
|
|
1109
1261
|
this.eatRegExpUnicodeEscapeSequence() ||
|
|
1110
1262
|
(!this.strict &&
|
|
1111
|
-
!this.
|
|
1263
|
+
!this._unicodeMode &&
|
|
1112
1264
|
this.eatLegacyOctalEscapeSequence()) ||
|
|
1113
1265
|
this.eatIdentityEscape()) {
|
|
1114
1266
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
@@ -1133,18 +1285,31 @@ class RegExpValidator {
|
|
|
1133
1285
|
const start = this.index;
|
|
1134
1286
|
if (this.eat(LEFT_SQUARE_BRACKET)) {
|
|
1135
1287
|
const negate = this.eat(CIRCUMFLEX_ACCENT);
|
|
1136
|
-
this.onCharacterClassEnter(start, negate);
|
|
1137
|
-
this.
|
|
1288
|
+
this.onCharacterClassEnter(start, negate, this._unicodeSetsMode);
|
|
1289
|
+
const result = this.consumeClassContents();
|
|
1138
1290
|
if (!this.eat(RIGHT_SQUARE_BRACKET)) {
|
|
1139
|
-
this.
|
|
1291
|
+
if (this.currentCodePoint === -1) {
|
|
1292
|
+
this.raise("Unterminated character class");
|
|
1293
|
+
}
|
|
1294
|
+
this.raise("Invalid character in character class");
|
|
1295
|
+
}
|
|
1296
|
+
if (negate && result.mayContainStrings) {
|
|
1297
|
+
this.raise("Negated character class may contain strings");
|
|
1140
1298
|
}
|
|
1141
1299
|
this.onCharacterClassLeave(start, this.index, negate);
|
|
1142
|
-
return
|
|
1300
|
+
return result;
|
|
1143
1301
|
}
|
|
1144
|
-
return
|
|
1302
|
+
return null;
|
|
1145
1303
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1304
|
+
consumeClassContents() {
|
|
1305
|
+
if (this._unicodeSetsMode) {
|
|
1306
|
+
if (this.currentCodePoint === RIGHT_SQUARE_BRACKET) {
|
|
1307
|
+
return {};
|
|
1308
|
+
}
|
|
1309
|
+
const result = this.consumeClassSetExpression();
|
|
1310
|
+
return result;
|
|
1311
|
+
}
|
|
1312
|
+
const strict = this.strict || this._unicodeMode;
|
|
1148
1313
|
for (;;) {
|
|
1149
1314
|
const rangeStart = this.index;
|
|
1150
1315
|
if (!this.consumeClassAtom()) {
|
|
@@ -1170,6 +1335,7 @@ class RegExpValidator {
|
|
|
1170
1335
|
}
|
|
1171
1336
|
this.onCharacterClassRange(rangeStart, this.index, min, max);
|
|
1172
1337
|
}
|
|
1338
|
+
return {};
|
|
1173
1339
|
}
|
|
1174
1340
|
consumeClassAtom() {
|
|
1175
1341
|
const start = this.index;
|
|
@@ -1192,7 +1358,7 @@ class RegExpValidator {
|
|
|
1192
1358
|
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1193
1359
|
return true;
|
|
1194
1360
|
}
|
|
1195
|
-
if (this.strict || this.
|
|
1361
|
+
if (this.strict || this._unicodeMode) {
|
|
1196
1362
|
this.raise("Invalid escape");
|
|
1197
1363
|
}
|
|
1198
1364
|
this.rewind(start);
|
|
@@ -1206,14 +1372,14 @@ class RegExpValidator {
|
|
|
1206
1372
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1207
1373
|
return true;
|
|
1208
1374
|
}
|
|
1209
|
-
if (this.
|
|
1375
|
+
if (this._unicodeMode && this.eat(HYPHEN_MINUS)) {
|
|
1210
1376
|
this._lastIntValue = HYPHEN_MINUS;
|
|
1211
1377
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1212
1378
|
return true;
|
|
1213
1379
|
}
|
|
1214
1380
|
let cp = 0;
|
|
1215
1381
|
if (!this.strict &&
|
|
1216
|
-
!this.
|
|
1382
|
+
!this._unicodeMode &&
|
|
1217
1383
|
this.currentCodePoint === LATIN_SMALL_LETTER_C &&
|
|
1218
1384
|
(isDecimalDigit((cp = this.nextCodePoint)) || cp === LOW_LINE)) {
|
|
1219
1385
|
this.advance();
|
|
@@ -1222,7 +1388,196 @@ class RegExpValidator {
|
|
|
1222
1388
|
this.onCharacter(start - 1, this.index, this._lastIntValue);
|
|
1223
1389
|
return true;
|
|
1224
1390
|
}
|
|
1225
|
-
return (this.consumeCharacterClassEscape() ||
|
|
1391
|
+
return (Boolean(this.consumeCharacterClassEscape()) ||
|
|
1392
|
+
this.consumeCharacterEscape());
|
|
1393
|
+
}
|
|
1394
|
+
consumeClassSetExpression() {
|
|
1395
|
+
const start = this.index;
|
|
1396
|
+
let mayContainStrings = false;
|
|
1397
|
+
let result = null;
|
|
1398
|
+
if (this.consumeClassSetCharacter()) {
|
|
1399
|
+
if (this.consumeClassSetRangeFromOperator(start)) {
|
|
1400
|
+
this.consumeClassUnionRight({});
|
|
1401
|
+
return {};
|
|
1402
|
+
}
|
|
1403
|
+
mayContainStrings = false;
|
|
1404
|
+
}
|
|
1405
|
+
else if ((result = this.consumeClassSetOperand())) {
|
|
1406
|
+
mayContainStrings = result.mayContainStrings;
|
|
1407
|
+
}
|
|
1408
|
+
else {
|
|
1409
|
+
const cp = this.currentCodePoint;
|
|
1410
|
+
if (cp === REVERSE_SOLIDUS) {
|
|
1411
|
+
this.advance();
|
|
1412
|
+
this.raise("Invalid escape");
|
|
1413
|
+
}
|
|
1414
|
+
if (cp === this.nextCodePoint &&
|
|
1415
|
+
isClassSetReservedDoublePunctuatorCharacter(cp)) {
|
|
1416
|
+
this.raise("Invalid set operation in character class");
|
|
1417
|
+
}
|
|
1418
|
+
this.raise("Invalid character in character class");
|
|
1419
|
+
}
|
|
1420
|
+
if (this.eat2(AMPERSAND, AMPERSAND)) {
|
|
1421
|
+
while (this.currentCodePoint !== AMPERSAND &&
|
|
1422
|
+
(result = this.consumeClassSetOperand())) {
|
|
1423
|
+
this.onClassIntersection(start, this.index);
|
|
1424
|
+
if (!result.mayContainStrings) {
|
|
1425
|
+
mayContainStrings = false;
|
|
1426
|
+
}
|
|
1427
|
+
if (this.eat2(AMPERSAND, AMPERSAND)) {
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
return { mayContainStrings };
|
|
1431
|
+
}
|
|
1432
|
+
this.raise("Invalid character in character class");
|
|
1433
|
+
}
|
|
1434
|
+
if (this.eat2(HYPHEN_MINUS, HYPHEN_MINUS)) {
|
|
1435
|
+
while (this.consumeClassSetOperand()) {
|
|
1436
|
+
this.onClassSubtraction(start, this.index);
|
|
1437
|
+
if (this.eat2(HYPHEN_MINUS, HYPHEN_MINUS)) {
|
|
1438
|
+
continue;
|
|
1439
|
+
}
|
|
1440
|
+
return { mayContainStrings };
|
|
1441
|
+
}
|
|
1442
|
+
this.raise("Invalid character in character class");
|
|
1443
|
+
}
|
|
1444
|
+
return this.consumeClassUnionRight({ mayContainStrings });
|
|
1445
|
+
}
|
|
1446
|
+
consumeClassUnionRight(leftResult) {
|
|
1447
|
+
let mayContainStrings = leftResult.mayContainStrings;
|
|
1448
|
+
for (;;) {
|
|
1449
|
+
const start = this.index;
|
|
1450
|
+
if (this.consumeClassSetCharacter()) {
|
|
1451
|
+
this.consumeClassSetRangeFromOperator(start);
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
const result = this.consumeClassSetOperand();
|
|
1455
|
+
if (result) {
|
|
1456
|
+
if (result.mayContainStrings) {
|
|
1457
|
+
mayContainStrings = true;
|
|
1458
|
+
}
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
break;
|
|
1462
|
+
}
|
|
1463
|
+
return { mayContainStrings };
|
|
1464
|
+
}
|
|
1465
|
+
consumeClassSetRangeFromOperator(start) {
|
|
1466
|
+
const currentStart = this.index;
|
|
1467
|
+
const min = this._lastIntValue;
|
|
1468
|
+
if (this.eat(HYPHEN_MINUS)) {
|
|
1469
|
+
if (this.consumeClassSetCharacter()) {
|
|
1470
|
+
const max = this._lastIntValue;
|
|
1471
|
+
if (min === -1 || max === -1) {
|
|
1472
|
+
this.raise("Invalid character class");
|
|
1473
|
+
}
|
|
1474
|
+
if (min > max) {
|
|
1475
|
+
this.raise("Range out of order in character class");
|
|
1476
|
+
}
|
|
1477
|
+
this.onCharacterClassRange(start, this.index, min, max);
|
|
1478
|
+
return true;
|
|
1479
|
+
}
|
|
1480
|
+
this.rewind(currentStart);
|
|
1481
|
+
}
|
|
1482
|
+
return false;
|
|
1483
|
+
}
|
|
1484
|
+
consumeClassSetOperand() {
|
|
1485
|
+
let result = null;
|
|
1486
|
+
if ((result = this.consumeNestedClass())) {
|
|
1487
|
+
return result;
|
|
1488
|
+
}
|
|
1489
|
+
if ((result = this.consumeClassStringDisjunction())) {
|
|
1490
|
+
return result;
|
|
1491
|
+
}
|
|
1492
|
+
if (this.consumeClassSetCharacter()) {
|
|
1493
|
+
return {};
|
|
1494
|
+
}
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
consumeNestedClass() {
|
|
1498
|
+
const start = this.index;
|
|
1499
|
+
if (this.eat(LEFT_SQUARE_BRACKET)) {
|
|
1500
|
+
const negate = this.eat(CIRCUMFLEX_ACCENT);
|
|
1501
|
+
this.onCharacterClassEnter(start, negate, true);
|
|
1502
|
+
const result = this.consumeClassContents();
|
|
1503
|
+
if (!this.eat(RIGHT_SQUARE_BRACKET)) {
|
|
1504
|
+
this.raise("Unterminated character class");
|
|
1505
|
+
}
|
|
1506
|
+
if (negate && result.mayContainStrings) {
|
|
1507
|
+
this.raise("Negated character class may contain strings");
|
|
1508
|
+
}
|
|
1509
|
+
this.onCharacterClassLeave(start, this.index, negate);
|
|
1510
|
+
return result;
|
|
1511
|
+
}
|
|
1512
|
+
if (this.eat(REVERSE_SOLIDUS)) {
|
|
1513
|
+
const result = this.consumeCharacterClassEscape();
|
|
1514
|
+
if (result) {
|
|
1515
|
+
return result;
|
|
1516
|
+
}
|
|
1517
|
+
this.rewind(start);
|
|
1518
|
+
}
|
|
1519
|
+
return null;
|
|
1520
|
+
}
|
|
1521
|
+
consumeClassStringDisjunction() {
|
|
1522
|
+
const start = this.index;
|
|
1523
|
+
if (this.eat3(REVERSE_SOLIDUS, LATIN_SMALL_LETTER_Q, LEFT_CURLY_BRACKET)) {
|
|
1524
|
+
this.onClassStringDisjunctionEnter(start);
|
|
1525
|
+
let i = 0;
|
|
1526
|
+
let mayContainStrings = false;
|
|
1527
|
+
do {
|
|
1528
|
+
if (this.consumeClassString(i++).mayContainStrings) {
|
|
1529
|
+
mayContainStrings = true;
|
|
1530
|
+
}
|
|
1531
|
+
} while (this.eat(VERTICAL_LINE));
|
|
1532
|
+
if (this.eat(RIGHT_CURLY_BRACKET)) {
|
|
1533
|
+
this.onClassStringDisjunctionLeave(start, this.index);
|
|
1534
|
+
return { mayContainStrings };
|
|
1535
|
+
}
|
|
1536
|
+
this.raise("Unterminated class string disjunction");
|
|
1537
|
+
}
|
|
1538
|
+
return null;
|
|
1539
|
+
}
|
|
1540
|
+
consumeClassString(i) {
|
|
1541
|
+
const start = this.index;
|
|
1542
|
+
let count = 0;
|
|
1543
|
+
this.onStringAlternativeEnter(start, i);
|
|
1544
|
+
while (this.currentCodePoint !== -1 &&
|
|
1545
|
+
this.consumeClassSetCharacter()) {
|
|
1546
|
+
count++;
|
|
1547
|
+
}
|
|
1548
|
+
this.onStringAlternativeLeave(start, this.index, i);
|
|
1549
|
+
return { mayContainStrings: count !== 1 };
|
|
1550
|
+
}
|
|
1551
|
+
consumeClassSetCharacter() {
|
|
1552
|
+
const start = this.index;
|
|
1553
|
+
const cp = this.currentCodePoint;
|
|
1554
|
+
if (cp !== this.nextCodePoint ||
|
|
1555
|
+
!isClassSetReservedDoublePunctuatorCharacter(cp)) {
|
|
1556
|
+
if (cp !== -1 && !isClassSetSyntaxCharacter(cp)) {
|
|
1557
|
+
this._lastIntValue = cp;
|
|
1558
|
+
this.advance();
|
|
1559
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1560
|
+
return true;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
if (this.eat(REVERSE_SOLIDUS)) {
|
|
1564
|
+
if (this.consumeCharacterEscape()) {
|
|
1565
|
+
return true;
|
|
1566
|
+
}
|
|
1567
|
+
if (isClassSetReservedPunctuator(this.currentCodePoint)) {
|
|
1568
|
+
this._lastIntValue = this.currentCodePoint;
|
|
1569
|
+
this.advance();
|
|
1570
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1571
|
+
return true;
|
|
1572
|
+
}
|
|
1573
|
+
if (this.eat(LATIN_SMALL_LETTER_B)) {
|
|
1574
|
+
this._lastIntValue = BACKSPACE;
|
|
1575
|
+
this.onCharacter(start, this.index, this._lastIntValue);
|
|
1576
|
+
return true;
|
|
1577
|
+
}
|
|
1578
|
+
this.rewind(start);
|
|
1579
|
+
}
|
|
1580
|
+
return false;
|
|
1226
1581
|
}
|
|
1227
1582
|
eatGroupName() {
|
|
1228
1583
|
if (this.eat(LESS_THAN_SIGN)) {
|
|
@@ -1245,7 +1600,7 @@ class RegExpValidator {
|
|
|
1245
1600
|
}
|
|
1246
1601
|
eatRegExpIdentifierStart() {
|
|
1247
1602
|
const start = this.index;
|
|
1248
|
-
const forceUFlag = !this.
|
|
1603
|
+
const forceUFlag = !this._unicodeMode && this.ecmaVersion >= 2020;
|
|
1249
1604
|
let cp = this.currentCodePoint;
|
|
1250
1605
|
this.advance();
|
|
1251
1606
|
if (cp === REVERSE_SOLIDUS &&
|
|
@@ -1258,7 +1613,7 @@ class RegExpValidator {
|
|
|
1258
1613
|
cp = combineSurrogatePair(cp, this.currentCodePoint);
|
|
1259
1614
|
this.advance();
|
|
1260
1615
|
}
|
|
1261
|
-
if (
|
|
1616
|
+
if (isIdentifierStartChar(cp)) {
|
|
1262
1617
|
this._lastIntValue = cp;
|
|
1263
1618
|
return true;
|
|
1264
1619
|
}
|
|
@@ -1269,7 +1624,7 @@ class RegExpValidator {
|
|
|
1269
1624
|
}
|
|
1270
1625
|
eatRegExpIdentifierPart() {
|
|
1271
1626
|
const start = this.index;
|
|
1272
|
-
const forceUFlag = !this.
|
|
1627
|
+
const forceUFlag = !this._unicodeMode && this.ecmaVersion >= 2020;
|
|
1273
1628
|
let cp = this.currentCodePoint;
|
|
1274
1629
|
this.advance();
|
|
1275
1630
|
if (cp === REVERSE_SOLIDUS &&
|
|
@@ -1282,7 +1637,7 @@ class RegExpValidator {
|
|
|
1282
1637
|
cp = combineSurrogatePair(cp, this.currentCodePoint);
|
|
1283
1638
|
this.advance();
|
|
1284
1639
|
}
|
|
1285
|
-
if (
|
|
1640
|
+
if (isIdentifierPartChar(cp)) {
|
|
1286
1641
|
this._lastIntValue = cp;
|
|
1287
1642
|
return true;
|
|
1288
1643
|
}
|
|
@@ -1344,7 +1699,7 @@ class RegExpValidator {
|
|
|
1344
1699
|
}
|
|
1345
1700
|
eatRegExpUnicodeEscapeSequence(forceUFlag = false) {
|
|
1346
1701
|
const start = this.index;
|
|
1347
|
-
const uFlag = forceUFlag || this.
|
|
1702
|
+
const uFlag = forceUFlag || this._unicodeMode;
|
|
1348
1703
|
if (this.eat(LATIN_SMALL_LETTER_U)) {
|
|
1349
1704
|
if ((uFlag && this.eatRegExpUnicodeSurrogatePairEscape()) ||
|
|
1350
1705
|
this.eatFixedHexDigits(4) ||
|
|
@@ -1400,7 +1755,7 @@ class RegExpValidator {
|
|
|
1400
1755
|
if (cp === -1) {
|
|
1401
1756
|
return false;
|
|
1402
1757
|
}
|
|
1403
|
-
if (this.
|
|
1758
|
+
if (this._unicodeMode) {
|
|
1404
1759
|
return isSyntaxCharacter(cp) || cp === SOLIDUS;
|
|
1405
1760
|
}
|
|
1406
1761
|
if (this.strict) {
|
|
@@ -1427,11 +1782,14 @@ class RegExpValidator {
|
|
|
1427
1782
|
eatUnicodePropertyValueExpression() {
|
|
1428
1783
|
const start = this.index;
|
|
1429
1784
|
if (this.eatUnicodePropertyName() && this.eat(EQUALS_SIGN)) {
|
|
1430
|
-
|
|
1785
|
+
const key = this._lastStrValue;
|
|
1431
1786
|
if (this.eatUnicodePropertyValue()) {
|
|
1432
|
-
|
|
1433
|
-
if (isValidUnicodeProperty(this.ecmaVersion,
|
|
1434
|
-
return
|
|
1787
|
+
const value = this._lastStrValue;
|
|
1788
|
+
if (isValidUnicodeProperty(this.ecmaVersion, key, value)) {
|
|
1789
|
+
return {
|
|
1790
|
+
key,
|
|
1791
|
+
value: value || null,
|
|
1792
|
+
};
|
|
1435
1793
|
}
|
|
1436
1794
|
this.raise("Invalid property name");
|
|
1437
1795
|
}
|
|
@@ -1440,18 +1798,28 @@ class RegExpValidator {
|
|
|
1440
1798
|
if (this.eatLoneUnicodePropertyNameOrValue()) {
|
|
1441
1799
|
const nameOrValue = this._lastStrValue;
|
|
1442
1800
|
if (isValidUnicodeProperty(this.ecmaVersion, "General_Category", nameOrValue)) {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1801
|
+
return {
|
|
1802
|
+
key: "General_Category",
|
|
1803
|
+
value: nameOrValue || null,
|
|
1804
|
+
};
|
|
1446
1805
|
}
|
|
1447
1806
|
if (isValidLoneUnicodeProperty(this.ecmaVersion, nameOrValue)) {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1807
|
+
return {
|
|
1808
|
+
key: nameOrValue,
|
|
1809
|
+
value: null,
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
if (this._unicodeSetsMode &&
|
|
1813
|
+
isValidLoneUnicodePropertyOfString(this.ecmaVersion, nameOrValue)) {
|
|
1814
|
+
return {
|
|
1815
|
+
key: nameOrValue,
|
|
1816
|
+
value: null,
|
|
1817
|
+
strings: true,
|
|
1818
|
+
};
|
|
1451
1819
|
}
|
|
1452
1820
|
this.raise("Invalid property name");
|
|
1453
1821
|
}
|
|
1454
|
-
return
|
|
1822
|
+
return null;
|
|
1455
1823
|
}
|
|
1456
1824
|
eatUnicodePropertyName() {
|
|
1457
1825
|
this._lastStrValue = "";
|
|
@@ -1478,7 +1846,7 @@ class RegExpValidator {
|
|
|
1478
1846
|
if (this.eatFixedHexDigits(2)) {
|
|
1479
1847
|
return true;
|
|
1480
1848
|
}
|
|
1481
|
-
if (this.
|
|
1849
|
+
if (this._unicodeMode || this.strict) {
|
|
1482
1850
|
this.raise("Invalid escape");
|
|
1483
1851
|
}
|
|
1484
1852
|
this.rewind(start);
|
|
@@ -1553,16 +1921,24 @@ class RegExpValidator {
|
|
|
1553
1921
|
const DUMMY_PATTERN = {};
|
|
1554
1922
|
const DUMMY_FLAGS = {};
|
|
1555
1923
|
const DUMMY_CAPTURING_GROUP = {};
|
|
1924
|
+
function isClassSetOperand(node) {
|
|
1925
|
+
return (node.type === "Character" ||
|
|
1926
|
+
node.type === "CharacterSet" ||
|
|
1927
|
+
node.type === "CharacterClass" ||
|
|
1928
|
+
node.type === "ExpressionCharacterClass" ||
|
|
1929
|
+
node.type === "ClassStringDisjunction");
|
|
1930
|
+
}
|
|
1556
1931
|
class RegExpParserState {
|
|
1557
1932
|
constructor(options) {
|
|
1558
1933
|
var _a;
|
|
1559
1934
|
this._node = DUMMY_PATTERN;
|
|
1935
|
+
this._expressionBuffer = null;
|
|
1560
1936
|
this._flags = DUMMY_FLAGS;
|
|
1561
1937
|
this._backreferences = [];
|
|
1562
1938
|
this._capturingGroups = [];
|
|
1563
1939
|
this.source = "";
|
|
1564
1940
|
this.strict = Boolean(options === null || options === void 0 ? void 0 : options.strict);
|
|
1565
|
-
this.ecmaVersion = (_a = options === null || options === void 0 ? void 0 : options.ecmaVersion) !== null && _a !== void 0 ? _a :
|
|
1941
|
+
this.ecmaVersion = (_a = options === null || options === void 0 ? void 0 : options.ecmaVersion) !== null && _a !== void 0 ? _a : latestEcmaVersion;
|
|
1566
1942
|
}
|
|
1567
1943
|
get pattern() {
|
|
1568
1944
|
if (this._node.type !== "Pattern") {
|
|
@@ -1576,7 +1952,7 @@ class RegExpParserState {
|
|
|
1576
1952
|
}
|
|
1577
1953
|
return this._flags;
|
|
1578
1954
|
}
|
|
1579
|
-
onRegExpFlags(start, end, { global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices, }) {
|
|
1955
|
+
onRegExpFlags(start, end, { global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices, unicodeSets, }) {
|
|
1580
1956
|
this._flags = {
|
|
1581
1957
|
type: "Flags",
|
|
1582
1958
|
parent: null,
|
|
@@ -1590,6 +1966,7 @@ class RegExpParserState {
|
|
|
1590
1966
|
sticky,
|
|
1591
1967
|
dotAll,
|
|
1592
1968
|
hasIndices,
|
|
1969
|
+
unicodeSets,
|
|
1593
1970
|
};
|
|
1594
1971
|
}
|
|
1595
1972
|
onPatternEnter(start) {
|
|
@@ -1804,26 +2181,33 @@ class RegExpParserState {
|
|
|
1804
2181
|
negate,
|
|
1805
2182
|
});
|
|
1806
2183
|
}
|
|
1807
|
-
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
|
|
2184
|
+
onUnicodePropertyCharacterSet(start, end, kind, key, value, negate, strings) {
|
|
1808
2185
|
const parent = this._node;
|
|
1809
|
-
if (parent.type !== "Alternative" &&
|
|
2186
|
+
if ((parent.type !== "Alternative" &&
|
|
2187
|
+
parent.type !== "CharacterClass") ||
|
|
2188
|
+
(strings && (negate || value))) {
|
|
1810
2189
|
throw new Error("UnknownError");
|
|
1811
2190
|
}
|
|
1812
|
-
|
|
2191
|
+
const base = {
|
|
1813
2192
|
type: "CharacterSet",
|
|
1814
2193
|
parent,
|
|
1815
2194
|
start,
|
|
1816
2195
|
end,
|
|
1817
2196
|
raw: this.source.slice(start, end),
|
|
1818
2197
|
kind,
|
|
2198
|
+
strings,
|
|
1819
2199
|
key,
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
2200
|
+
};
|
|
2201
|
+
const node = strings
|
|
2202
|
+
? Object.assign(Object.assign({}, base), { value: null, negate: false, strings: true }) : Object.assign(Object.assign({}, base), { value,
|
|
2203
|
+
negate, strings: false });
|
|
2204
|
+
parent.elements.push(node);
|
|
1823
2205
|
}
|
|
1824
2206
|
onCharacter(start, end, value) {
|
|
1825
2207
|
const parent = this._node;
|
|
1826
|
-
if (parent.type !== "Alternative" &&
|
|
2208
|
+
if (parent.type !== "Alternative" &&
|
|
2209
|
+
parent.type !== "CharacterClass" &&
|
|
2210
|
+
parent.type !== "StringAlternative") {
|
|
1827
2211
|
throw new Error("UnknownError");
|
|
1828
2212
|
}
|
|
1829
2213
|
parent.elements.push({
|
|
@@ -1852,31 +2236,66 @@ class RegExpParserState {
|
|
|
1852
2236
|
parent.elements.push(node);
|
|
1853
2237
|
this._backreferences.push(node);
|
|
1854
2238
|
}
|
|
1855
|
-
onCharacterClassEnter(start, negate) {
|
|
2239
|
+
onCharacterClassEnter(start, negate, unicodeSets) {
|
|
1856
2240
|
const parent = this._node;
|
|
1857
|
-
|
|
1858
|
-
throw new Error("UnknownError");
|
|
1859
|
-
}
|
|
1860
|
-
this._node = {
|
|
2241
|
+
const base = {
|
|
1861
2242
|
type: "CharacterClass",
|
|
1862
2243
|
parent,
|
|
1863
2244
|
start,
|
|
1864
2245
|
end: start,
|
|
1865
2246
|
raw: "",
|
|
2247
|
+
unicodeSets,
|
|
1866
2248
|
negate,
|
|
1867
2249
|
elements: [],
|
|
1868
2250
|
};
|
|
1869
|
-
parent.
|
|
2251
|
+
if (parent.type === "Alternative") {
|
|
2252
|
+
const node = Object.assign(Object.assign({}, base), { parent });
|
|
2253
|
+
this._node = node;
|
|
2254
|
+
parent.elements.push(node);
|
|
2255
|
+
}
|
|
2256
|
+
else if (parent.type === "CharacterClass" &&
|
|
2257
|
+
parent.unicodeSets &&
|
|
2258
|
+
unicodeSets) {
|
|
2259
|
+
const node = Object.assign(Object.assign({}, base), { parent,
|
|
2260
|
+
unicodeSets });
|
|
2261
|
+
this._node = node;
|
|
2262
|
+
parent.elements.push(node);
|
|
2263
|
+
}
|
|
2264
|
+
else {
|
|
2265
|
+
throw new Error("UnknownError");
|
|
2266
|
+
}
|
|
1870
2267
|
}
|
|
1871
2268
|
onCharacterClassLeave(start, end) {
|
|
1872
2269
|
const node = this._node;
|
|
1873
2270
|
if (node.type !== "CharacterClass" ||
|
|
1874
|
-
node.parent.type !== "Alternative"
|
|
2271
|
+
(node.parent.type !== "Alternative" &&
|
|
2272
|
+
node.parent.type !== "CharacterClass") ||
|
|
2273
|
+
(this._expressionBuffer && node.elements.length > 0)) {
|
|
1875
2274
|
throw new Error("UnknownError");
|
|
1876
2275
|
}
|
|
2276
|
+
const parent = node.parent;
|
|
1877
2277
|
node.end = end;
|
|
1878
2278
|
node.raw = this.source.slice(start, end);
|
|
1879
|
-
this._node =
|
|
2279
|
+
this._node = parent;
|
|
2280
|
+
const expression = this._expressionBuffer;
|
|
2281
|
+
this._expressionBuffer = null;
|
|
2282
|
+
if (!expression) {
|
|
2283
|
+
return;
|
|
2284
|
+
}
|
|
2285
|
+
const newNode = {
|
|
2286
|
+
type: "ExpressionCharacterClass",
|
|
2287
|
+
parent,
|
|
2288
|
+
start: node.start,
|
|
2289
|
+
end: node.end,
|
|
2290
|
+
raw: node.raw,
|
|
2291
|
+
negate: node.negate,
|
|
2292
|
+
expression,
|
|
2293
|
+
};
|
|
2294
|
+
expression.parent = newNode;
|
|
2295
|
+
if (node !== parent.elements.pop()) {
|
|
2296
|
+
throw new Error("UnknownError");
|
|
2297
|
+
}
|
|
2298
|
+
parent.elements.push(newNode);
|
|
1880
2299
|
}
|
|
1881
2300
|
onCharacterClassRange(start, end) {
|
|
1882
2301
|
const parent = this._node;
|
|
@@ -1885,15 +2304,19 @@ class RegExpParserState {
|
|
|
1885
2304
|
}
|
|
1886
2305
|
const elements = parent.elements;
|
|
1887
2306
|
const max = elements.pop();
|
|
1888
|
-
|
|
2307
|
+
if (!max || max.type !== "Character") {
|
|
2308
|
+
throw new Error("UnknownError");
|
|
2309
|
+
}
|
|
2310
|
+
if (!parent.unicodeSets) {
|
|
2311
|
+
const hyphen = elements.pop();
|
|
2312
|
+
if (!hyphen ||
|
|
2313
|
+
hyphen.type !== "Character" ||
|
|
2314
|
+
hyphen.value !== HYPHEN_MINUS) {
|
|
2315
|
+
throw new Error("UnknownError");
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
1889
2318
|
const min = elements.pop();
|
|
1890
|
-
if (!min ||
|
|
1891
|
-
!max ||
|
|
1892
|
-
!hyphen ||
|
|
1893
|
-
min.type !== "Character" ||
|
|
1894
|
-
max.type !== "Character" ||
|
|
1895
|
-
hyphen.type !== "Character" ||
|
|
1896
|
-
hyphen.value !== HYPHEN_MINUS) {
|
|
2319
|
+
if (!min || min.type !== "Character") {
|
|
1897
2320
|
throw new Error("UnknownError");
|
|
1898
2321
|
}
|
|
1899
2322
|
const node = {
|
|
@@ -1909,6 +2332,111 @@ class RegExpParserState {
|
|
|
1909
2332
|
max.parent = node;
|
|
1910
2333
|
elements.push(node);
|
|
1911
2334
|
}
|
|
2335
|
+
onClassIntersection(start, end) {
|
|
2336
|
+
var _a;
|
|
2337
|
+
const parent = this._node;
|
|
2338
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2339
|
+
throw new Error("UnknownError");
|
|
2340
|
+
}
|
|
2341
|
+
const right = parent.elements.pop();
|
|
2342
|
+
const left = (_a = this._expressionBuffer) !== null && _a !== void 0 ? _a : parent.elements.pop();
|
|
2343
|
+
if (!left ||
|
|
2344
|
+
!right ||
|
|
2345
|
+
left.type === "ClassSubtraction" ||
|
|
2346
|
+
(left.type !== "ClassIntersection" && !isClassSetOperand(left)) ||
|
|
2347
|
+
!isClassSetOperand(right)) {
|
|
2348
|
+
throw new Error("UnknownError");
|
|
2349
|
+
}
|
|
2350
|
+
const node = {
|
|
2351
|
+
type: "ClassIntersection",
|
|
2352
|
+
parent: parent,
|
|
2353
|
+
start,
|
|
2354
|
+
end,
|
|
2355
|
+
raw: this.source.slice(start, end),
|
|
2356
|
+
left,
|
|
2357
|
+
right,
|
|
2358
|
+
};
|
|
2359
|
+
left.parent = node;
|
|
2360
|
+
right.parent = node;
|
|
2361
|
+
this._expressionBuffer = node;
|
|
2362
|
+
}
|
|
2363
|
+
onClassSubtraction(start, end) {
|
|
2364
|
+
var _a;
|
|
2365
|
+
const parent = this._node;
|
|
2366
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2367
|
+
throw new Error("UnknownError");
|
|
2368
|
+
}
|
|
2369
|
+
const right = parent.elements.pop();
|
|
2370
|
+
const left = (_a = this._expressionBuffer) !== null && _a !== void 0 ? _a : parent.elements.pop();
|
|
2371
|
+
if (!left ||
|
|
2372
|
+
!right ||
|
|
2373
|
+
left.type === "ClassIntersection" ||
|
|
2374
|
+
(left.type !== "ClassSubtraction" && !isClassSetOperand(left)) ||
|
|
2375
|
+
!isClassSetOperand(right)) {
|
|
2376
|
+
throw new Error("UnknownError");
|
|
2377
|
+
}
|
|
2378
|
+
const node = {
|
|
2379
|
+
type: "ClassSubtraction",
|
|
2380
|
+
parent: parent,
|
|
2381
|
+
start,
|
|
2382
|
+
end,
|
|
2383
|
+
raw: this.source.slice(start, end),
|
|
2384
|
+
left,
|
|
2385
|
+
right,
|
|
2386
|
+
};
|
|
2387
|
+
left.parent = node;
|
|
2388
|
+
right.parent = node;
|
|
2389
|
+
this._expressionBuffer = node;
|
|
2390
|
+
}
|
|
2391
|
+
onClassStringDisjunctionEnter(start) {
|
|
2392
|
+
const parent = this._node;
|
|
2393
|
+
if (parent.type !== "CharacterClass" || !parent.unicodeSets) {
|
|
2394
|
+
throw new Error("UnknownError");
|
|
2395
|
+
}
|
|
2396
|
+
this._node = {
|
|
2397
|
+
type: "ClassStringDisjunction",
|
|
2398
|
+
parent,
|
|
2399
|
+
start,
|
|
2400
|
+
end: start,
|
|
2401
|
+
raw: "",
|
|
2402
|
+
alternatives: [],
|
|
2403
|
+
};
|
|
2404
|
+
parent.elements.push(this._node);
|
|
2405
|
+
}
|
|
2406
|
+
onClassStringDisjunctionLeave(start, end) {
|
|
2407
|
+
const node = this._node;
|
|
2408
|
+
if (node.type !== "ClassStringDisjunction" ||
|
|
2409
|
+
node.parent.type !== "CharacterClass") {
|
|
2410
|
+
throw new Error("UnknownError");
|
|
2411
|
+
}
|
|
2412
|
+
node.end = end;
|
|
2413
|
+
node.raw = this.source.slice(start, end);
|
|
2414
|
+
this._node = node.parent;
|
|
2415
|
+
}
|
|
2416
|
+
onStringAlternativeEnter(start) {
|
|
2417
|
+
const parent = this._node;
|
|
2418
|
+
if (parent.type !== "ClassStringDisjunction") {
|
|
2419
|
+
throw new Error("UnknownError");
|
|
2420
|
+
}
|
|
2421
|
+
this._node = {
|
|
2422
|
+
type: "StringAlternative",
|
|
2423
|
+
parent,
|
|
2424
|
+
start,
|
|
2425
|
+
end: start,
|
|
2426
|
+
raw: "",
|
|
2427
|
+
elements: [],
|
|
2428
|
+
};
|
|
2429
|
+
parent.alternatives.push(this._node);
|
|
2430
|
+
}
|
|
2431
|
+
onStringAlternativeLeave(start, end) {
|
|
2432
|
+
const node = this._node;
|
|
2433
|
+
if (node.type !== "StringAlternative") {
|
|
2434
|
+
throw new Error("UnknownError");
|
|
2435
|
+
}
|
|
2436
|
+
node.end = end;
|
|
2437
|
+
node.raw = this.source.slice(start, end);
|
|
2438
|
+
this._node = node.parent;
|
|
2439
|
+
}
|
|
1912
2440
|
}
|
|
1913
2441
|
class RegExpParser {
|
|
1914
2442
|
constructor(options) {
|
|
@@ -1938,9 +2466,9 @@ class RegExpParser {
|
|
|
1938
2466
|
this._validator.validateFlags(source, start, end);
|
|
1939
2467
|
return this._state.flags;
|
|
1940
2468
|
}
|
|
1941
|
-
parsePattern(source, start = 0, end = source.length,
|
|
2469
|
+
parsePattern(source, start = 0, end = source.length, uFlagOrFlags = undefined) {
|
|
1942
2470
|
this._state.source = source;
|
|
1943
|
-
this._validator.validatePattern(source, start, end,
|
|
2471
|
+
this._validator.validatePattern(source, start, end, uFlagOrFlags);
|
|
1944
2472
|
return this._state.pattern;
|
|
1945
2473
|
}
|
|
1946
2474
|
}
|
|
@@ -1975,6 +2503,18 @@ class RegExpVisitor {
|
|
|
1975
2503
|
case "CharacterSet":
|
|
1976
2504
|
this.visitCharacterSet(node);
|
|
1977
2505
|
break;
|
|
2506
|
+
case "ClassIntersection":
|
|
2507
|
+
this.visitClassIntersection(node);
|
|
2508
|
+
break;
|
|
2509
|
+
case "ClassStringDisjunction":
|
|
2510
|
+
this.visitClassStringDisjunction(node);
|
|
2511
|
+
break;
|
|
2512
|
+
case "ClassSubtraction":
|
|
2513
|
+
this.visitClassSubtraction(node);
|
|
2514
|
+
break;
|
|
2515
|
+
case "ExpressionCharacterClass":
|
|
2516
|
+
this.visitExpressionCharacterClass(node);
|
|
2517
|
+
break;
|
|
1978
2518
|
case "Flags":
|
|
1979
2519
|
this.visitFlags(node);
|
|
1980
2520
|
break;
|
|
@@ -1990,6 +2530,9 @@ class RegExpVisitor {
|
|
|
1990
2530
|
case "RegExpLiteral":
|
|
1991
2531
|
this.visitRegExpLiteral(node);
|
|
1992
2532
|
break;
|
|
2533
|
+
case "StringAlternative":
|
|
2534
|
+
this.visitStringAlternative(node);
|
|
2535
|
+
break;
|
|
1993
2536
|
default:
|
|
1994
2537
|
throw new Error(`Unknown type: ${node.type}`);
|
|
1995
2538
|
}
|
|
@@ -2066,6 +2609,44 @@ class RegExpVisitor {
|
|
|
2066
2609
|
this._handlers.onCharacterSetLeave(node);
|
|
2067
2610
|
}
|
|
2068
2611
|
}
|
|
2612
|
+
visitClassIntersection(node) {
|
|
2613
|
+
if (this._handlers.onClassIntersectionEnter) {
|
|
2614
|
+
this._handlers.onClassIntersectionEnter(node);
|
|
2615
|
+
}
|
|
2616
|
+
this.visit(node.left);
|
|
2617
|
+
this.visit(node.right);
|
|
2618
|
+
if (this._handlers.onClassIntersectionLeave) {
|
|
2619
|
+
this._handlers.onClassIntersectionLeave(node);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
visitClassStringDisjunction(node) {
|
|
2623
|
+
if (this._handlers.onClassStringDisjunctionEnter) {
|
|
2624
|
+
this._handlers.onClassStringDisjunctionEnter(node);
|
|
2625
|
+
}
|
|
2626
|
+
node.alternatives.forEach(this.visit, this);
|
|
2627
|
+
if (this._handlers.onClassStringDisjunctionLeave) {
|
|
2628
|
+
this._handlers.onClassStringDisjunctionLeave(node);
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
visitClassSubtraction(node) {
|
|
2632
|
+
if (this._handlers.onClassSubtractionEnter) {
|
|
2633
|
+
this._handlers.onClassSubtractionEnter(node);
|
|
2634
|
+
}
|
|
2635
|
+
this.visit(node.left);
|
|
2636
|
+
this.visit(node.right);
|
|
2637
|
+
if (this._handlers.onClassSubtractionLeave) {
|
|
2638
|
+
this._handlers.onClassSubtractionLeave(node);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
visitExpressionCharacterClass(node) {
|
|
2642
|
+
if (this._handlers.onExpressionCharacterClassEnter) {
|
|
2643
|
+
this._handlers.onExpressionCharacterClassEnter(node);
|
|
2644
|
+
}
|
|
2645
|
+
this.visit(node.expression);
|
|
2646
|
+
if (this._handlers.onExpressionCharacterClassLeave) {
|
|
2647
|
+
this._handlers.onExpressionCharacterClassLeave(node);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2069
2650
|
visitFlags(node) {
|
|
2070
2651
|
if (this._handlers.onFlagsEnter) {
|
|
2071
2652
|
this._handlers.onFlagsEnter(node);
|
|
@@ -2111,6 +2692,15 @@ class RegExpVisitor {
|
|
|
2111
2692
|
this._handlers.onRegExpLiteralLeave(node);
|
|
2112
2693
|
}
|
|
2113
2694
|
}
|
|
2695
|
+
visitStringAlternative(node) {
|
|
2696
|
+
if (this._handlers.onStringAlternativeEnter) {
|
|
2697
|
+
this._handlers.onStringAlternativeEnter(node);
|
|
2698
|
+
}
|
|
2699
|
+
node.elements.forEach(this.visit, this);
|
|
2700
|
+
if (this._handlers.onStringAlternativeLeave) {
|
|
2701
|
+
this._handlers.onStringAlternativeLeave(node);
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2114
2704
|
}
|
|
2115
2705
|
|
|
2116
2706
|
function parseRegExpLiteral(source, options) {
|