@@ -40,49 +40,49 @@ export class RegExpValidationState {
40
40
41
41
// If u flag is given, this returns the code point at the index (it combines a surrogate pair).
42
42
// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
43
- at ( i ) {
43
+ at ( i , forceU = false ) {
44
44
const s = this . source
45
45
const l = s . length
46
46
if ( i >= l ) {
47
47
return - 1
48
48
}
49
49
const c = s . charCodeAt ( i )
50
- if ( ! this . switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ) {
50
+ if ( ! ( forceU || this . switchU ) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ) {
51
51
return c
52
52
}
53
53
const next = s . charCodeAt ( i + 1 )
54
54
return next >= 0xDC00 && next <= 0xDFFF ? ( c << 10 ) + next - 0x35FDC00 : c
55
55
}
56
56
57
- nextIndex ( i ) {
57
+ nextIndex ( i , forceU = false ) {
58
58
const s = this . source
59
59
const l = s . length
60
60
if ( i >= l ) {
61
61
return l
62
62
}
63
63
let c = s . charCodeAt ( i ) , next
64
- if ( ! this . switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
64
+ if ( ! ( forceU || this . switchU ) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
65
65
( next = s . charCodeAt ( i + 1 ) ) < 0xDC00 || next > 0xDFFF ) {
66
66
return i + 1
67
67
}
68
68
return i + 2
69
69
}
70
70
71
- current ( ) {
72
- return this . at ( this . pos )
71
+ current ( forceU = false ) {
72
+ return this . at ( this . pos , forceU )
73
73
}
74
74
75
- lookahead ( ) {
76
- return this . at ( this . nextIndex ( this . pos ) )
75
+ lookahead ( forceU = false ) {
76
+ return this . at ( this . nextIndex ( this . pos , forceU ) , forceU )
77
77
}
78
78
79
- advance ( ) {
80
- this . pos = this . nextIndex ( this . pos )
79
+ advance ( forceU = false ) {
80
+ this . pos = this . nextIndex ( this . pos , forceU )
81
81
}
82
82
83
- eat ( ch ) {
84
- if ( this . current ( ) === ch ) {
85
- this . advance ( )
83
+ eat ( ch , forceU = false ) {
84
+ if ( this . current ( forceU ) === ch ) {
85
+ this . advance ( forceU )
86
86
return true
87
87
}
88
88
return false
@@ -418,9 +418,9 @@ pp.regexp_eatExtendedPatternCharacter = function(state) {
418
418
return false
419
419
}
420
420
421
- // GroupSpecifier[U] ::
421
+ // GroupSpecifier ::
422
422
// [empty]
423
- // `?` GroupName[?U]
423
+ // `?` GroupName
424
424
pp . regexp_groupSpecifier = function ( state ) {
425
425
if ( state . eat ( 0x3F /* ? */ ) ) {
426
426
if ( this . regexp_eatGroupName ( state ) ) {
@@ -434,8 +434,8 @@ pp.regexp_groupSpecifier = function(state) {
434
434
}
435
435
}
436
436
437
- // GroupName[U] ::
438
- // `<` RegExpIdentifierName[?U] `>`
437
+ // GroupName ::
438
+ // `<` RegExpIdentifierName `>`
439
439
// Note: this updates `state.lastStringValue` property with the eaten name.
440
440
pp . regexp_eatGroupName = function ( state ) {
441
441
state . lastStringValue = ""
@@ -448,9 +448,9 @@ pp.regexp_eatGroupName = function(state) {
448
448
return false
449
449
}
450
450
451
- // RegExpIdentifierName[U] ::
452
- // RegExpIdentifierStart[?U]
453
- // RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
451
+ // RegExpIdentifierName ::
452
+ // RegExpIdentifierStart
453
+ // RegExpIdentifierName RegExpIdentifierPart
454
454
// Note: this updates `state.lastStringValue` property with the eaten name.
455
455
pp . regexp_eatRegExpIdentifierName = function ( state ) {
456
456
state . lastStringValue = ""
@@ -464,17 +464,18 @@ pp.regexp_eatRegExpIdentifierName = function(state) {
464
464
return false
465
465
}
466
466
467
- // RegExpIdentifierStart[U] ::
467
+ // RegExpIdentifierStart ::
468
468
// UnicodeIDStart
469
469
// `$`
470
470
// `_`
471
- // `\` RegExpUnicodeEscapeSequence[? U]
471
+ // `\` RegExpUnicodeEscapeSequence[+ U]
472
472
pp . regexp_eatRegExpIdentifierStart = function ( state ) {
473
473
const start = state . pos
474
- let ch = state . current ( )
475
- state . advance ( )
474
+ const forceU = this . options . ecmaVersion >= 11
475
+ let ch = state . current ( forceU )
476
+ state . advance ( forceU )
476
477
477
- if ( ch === 0x5C /* \ */ && this . regexp_eatRegExpUnicodeEscapeSequence ( state ) ) {
478
+ if ( ch === 0x5C /* \ */ && this . regexp_eatRegExpUnicodeEscapeSequence ( state , forceU ) ) {
478
479
ch = state . lastIntValue
479
480
}
480
481
if ( isRegExpIdentifierStart ( ch ) ) {
@@ -489,19 +490,20 @@ function isRegExpIdentifierStart(ch) {
489
490
return isIdentifierStart ( ch , true ) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
490
491
}
491
492
492
- // RegExpIdentifierPart[U] ::
493
+ // RegExpIdentifierPart ::
493
494
// UnicodeIDContinue
494
495
// `$`
495
496
// `_`
496
- // `\` RegExpUnicodeEscapeSequence[? U]
497
+ // `\` RegExpUnicodeEscapeSequence[+ U]
497
498
// <ZWNJ>
498
499
// <ZWJ>
499
500
pp . regexp_eatRegExpIdentifierPart = function ( state ) {
500
501
const start = state . pos
501
- let ch = state . current ( )
502
- state . advance ( )
502
+ const forceU = this . options . ecmaVersion >= 11
503
+ let ch = state . current ( forceU )
504
+ state . advance ( forceU )
503
505
504
- if ( ch === 0x5C /* \ */ && this . regexp_eatRegExpUnicodeEscapeSequence ( state ) ) {
506
+ if ( ch === 0x5C /* \ */ && this . regexp_eatRegExpUnicodeEscapeSequence ( state , forceU ) ) {
505
507
ch = state . lastIntValue
506
508
}
507
509
if ( isRegExpIdentifierPart ( ch ) ) {
@@ -571,7 +573,7 @@ pp.regexp_eatCharacterEscape = function(state) {
571
573
this . regexp_eatCControlLetter ( state ) ||
572
574
this . regexp_eatZero ( state ) ||
573
575
this . regexp_eatHexEscapeSequence ( state ) ||
574
- this . regexp_eatRegExpUnicodeEscapeSequence ( state ) ||
576
+ this . regexp_eatRegExpUnicodeEscapeSequence ( state , false ) ||
575
577
( ! state . switchU && this . regexp_eatLegacyOctalEscapeSequence ( state ) ) ||
576
578
this . regexp_eatIdentityEscape ( state )
577
579
)
@@ -644,13 +646,14 @@ function isControlLetter(ch) {
644
646
}
645
647
646
648
// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
647
- pp . regexp_eatRegExpUnicodeEscapeSequence = function ( state ) {
649
+ pp . regexp_eatRegExpUnicodeEscapeSequence = function ( state , forceU = false ) {
648
650
const start = state . pos
651
+ const switchU = forceU || state . switchU
649
652
650
653
if ( state . eat ( 0x75 /* u */ ) ) {
651
654
if ( this . regexp_eatFixedHexDigits ( state , 4 ) ) {
652
655
const lead = state . lastIntValue
653
- if ( state . switchU && lead >= 0xD800 && lead <= 0xDBFF ) {
656
+ if ( switchU && lead >= 0xD800 && lead <= 0xDBFF ) {
654
657
const leadSurrogateEnd = state . pos
655
658
if ( state . eat ( 0x5C /* \ */ ) && state . eat ( 0x75 /* u */ ) && this . regexp_eatFixedHexDigits ( state , 4 ) ) {
656
659
const trail = state . lastIntValue
@@ -665,15 +668,15 @@ pp.regexp_eatRegExpUnicodeEscapeSequence = function(state) {
665
668
return true
666
669
}
667
670
if (
668
- state . switchU &&
671
+ switchU &&
669
672
state . eat ( 0x7B /* { */ ) &&
670
673
this . regexp_eatHexDigits ( state ) &&
671
674
state . eat ( 0x7D /* } */ ) &&
672
675
isValidUnicode ( state . lastIntValue )
673
676
) {
674
677
return true
675
678
}
676
- if ( state . switchU ) {
679
+ if ( switchU ) {
677
680
state . raise ( "Invalid unicode escape" )
678
681
}
679
682
state . pos = start
0 commit comments