@@ -1415,6 +1415,21 @@ export function createScanner(languageVersion: ScriptTarget,
1415
1415
return resultingToken ;
1416
1416
}
1417
1417
1418
+ // Extract from Section A.1
1419
+ // EscapeSequence ::
1420
+ // | CharacterEscapeSequence
1421
+ // | 0 (?![0-9])
1422
+ // | LegacyOctalEscapeSequence
1423
+ // | NonOctalDecimalEscapeSequence
1424
+ // | HexEscapeSequence
1425
+ // | UnicodeEscapeSequence
1426
+ // LegacyOctalEscapeSequence ::=
1427
+ // | '0' (?=[89])
1428
+ // | [1-7] (?![0-7])
1429
+ // | [0-3] [0-7] (?![0-7])
1430
+ // | [4-7] [0-7]
1431
+ // | [0-3] [0-7] [0-7]
1432
+ // NonOctalDecimalEscapeSequence ::= [89]
1418
1433
function scanEscapeSequence ( shouldEmitInvalidEscapeError ?: boolean ) : string {
1419
1434
const start = pos ;
1420
1435
pos ++ ;
@@ -1426,8 +1441,9 @@ export function createScanner(languageVersion: ScriptTarget,
1426
1441
pos ++ ;
1427
1442
switch ( ch ) {
1428
1443
case CharacterCodes . _0 :
1429
- // '\08' is '\0' + '8' but is treated as an octal escape sequence, thus isDigit
1430
- if ( ! ( pos < end && isDigit ( text . charCodeAt ( pos ) ) ) ) {
1444
+ // Although '0' preceding any digit is treated as LegacyOctalEscapeSequence,
1445
+ // '\08' should separately be interpreted as '\0' + '8'.
1446
+ if ( pos >= end || ! isDigit ( text . charCodeAt ( pos ) ) ) {
1431
1447
return "\0" ;
1432
1448
}
1433
1449
// '\01', '\011'
@@ -1462,7 +1478,7 @@ export function createScanner(languageVersion: ScriptTarget,
1462
1478
// the invalid '\8' and '\9'
1463
1479
tokenFlags |= TokenFlags . ContainsInvalidEscape ;
1464
1480
if ( shouldEmitInvalidEscapeError ) {
1465
- error ( Diagnostics . _0_is_not_allowed , start , 2 , text . substring ( start , pos ) ) ;
1481
+ error ( Diagnostics . Escape_sequence_0_is_not_allowed , start , pos - start , text . substring ( start , pos ) ) ;
1466
1482
return String . fromCharCode ( ch ) ;
1467
1483
}
1468
1484
return text . substring ( start , pos ) ;
0 commit comments