Skip to content

Commit

Permalink
feat(lexer): support new RegExp Indices flag "d"
Browse files Browse the repository at this point in the history
Related to #214
  • Loading branch information
3cp committed May 1, 2022
1 parent f6c694b commit 4174428
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 38 deletions.
24 changes: 16 additions & 8 deletions src/lexer/regexp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ export function scanRegularExpression(parser: ParserState, context: Context): To
const bodyEnd = parser.index - 1;

const enum RegexFlags {
Empty = 0b000000,
IgnoreCase = 0b000001,
Global = 0b000010,
Multiline = 0b000100,
Unicode = 0b010000,
Sticky = 0b001000,
DotAll = 0b100000
Empty = 0b0000000,
IgnoreCase = 0b0000001,
Global = 0b0000010,
Multiline = 0b0000100,
Unicode = 0b0010000,
Sticky = 0b0001000,
DotAll = 0b0100000,
Indices = 0b1000000
}

let mask = RegexFlags.Empty;
Expand All @@ -91,7 +92,7 @@ export function scanRegularExpression(parser: ParserState, context: Context): To
break;

case Chars.LowerU:
if (mask & RegexFlags.Unicode) report(parser, Errors.DuplicateRegExpFlag, 'g');
if (mask & RegexFlags.Unicode) report(parser, Errors.DuplicateRegExpFlag, 'u');
mask |= RegexFlags.Unicode;
break;

Expand All @@ -105,6 +106,11 @@ export function scanRegularExpression(parser: ParserState, context: Context): To
mask |= RegexFlags.DotAll;
break;

case Chars.LowerD:
if (mask & RegexFlags.Indices) report(parser, Errors.DuplicateRegExpFlag, 'd');
mask |= RegexFlags.Indices;
break;

default:
report(parser, Errors.UnexpectedTokenRegExpFlag);
}
Expand Down Expand Up @@ -136,6 +142,8 @@ export function scanRegularExpression(parser: ParserState, context: Context): To
*/
function validate(parser: ParserState, pattern: string, flags: string): RegExp | null | Token {
try {
// Temporarily allows older version of Nodejs (or browser) to accept the new Indices flag "d".
flags = flags.replace('d', '');
return new RegExp(pattern, flags);
} catch (e) {
report(parser, Errors.UnterminatedRegExp);
Expand Down
55 changes: 25 additions & 30 deletions test/lexer/regexp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ describe('Lexer - Regular expressions', () => {
[Context.AllowRegExp, '/a{,61}/', 'a{,61}', ''],
[Context.AllowRegExp, '/foo/gy', 'foo', 'gy'],
[Context.AllowRegExp, '/foo/igy', 'foo', 'igy'],
[Context.AllowRegExp, '/foo/d', 'foo', 'd'],
[Context.AllowRegExp, '/foo/musd', 'foo', 'musd'],
[Context.AllowRegExp, '/\\D/', '\\D', ''],
[Context.AllowRegExp, '/\\r/', '\\r', ''],
[Context.AllowRegExp, '/\\s/', '\\s', ''],
Expand Down Expand Up @@ -171,21 +173,19 @@ describe('Lexer - Regular expressions', () => {
t.throws(() => scanSingleToken(state, context, 0));
});
}
fail('fails on /i/ii', '/ ', Context.AllowRegExp);
fail('fails on /i/ii', '/\n$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\r$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2029$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/$\r/', Context.AllowRegExp);
fail('fails on /i/ii', '/$\u2028/', Context.AllowRegExp);
fail('fails on /i/ii', '/$\u2029/', Context.AllowRegExp);
fail('fails on /i/ii', '/i/igui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/mmgui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ggui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/guui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /', '/ ', Context.AllowRegExp);
fail('fails on /\n$/\n', '/\n$/\n', Context.AllowRegExp);
fail('fails on /\r$/\n', '/\r$/\n', Context.AllowRegExp);
fail('fails on /\u2028$/\n', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /\u2029$/\n', '/\u2029$/\n', Context.AllowRegExp);
fail('fails on /\u2028$/\n', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /$\r/', '/$\r/', Context.AllowRegExp);
fail('fails on /$\u2028/', '/$\u2028/', Context.AllowRegExp);
fail('fails on /$\u2029/', '/$\u2029/', Context.AllowRegExp);
fail('fails on /i/igui', '/i/igui', Context.AllowRegExp);
fail('fails on /i/mmgui', '/i/mmgui', Context.AllowRegExp);
fail('fails on /i/ggui', '/i/ggui', Context.AllowRegExp);
fail('fails on /i/guui', '/i/guui', Context.AllowRegExp);
fail('fails on /\\B*/u', '/\\B*/u', Context.AllowRegExp);
fail('fails on \\b+/u', '\\b+/u', Context.AllowRegExp);
fail('fails on /[d-G\\r]/', '/[d-G\\r]/', Context.AllowRegExp);
Expand All @@ -195,21 +195,16 @@ describe('Lexer - Regular expressions', () => {
fail('fails on /{1,}/', '/{1,}/', Context.AllowRegExp);
fail('fails on /x{1,}{1}/', '/x{1,}{1}/', Context.AllowRegExp);
fail('fails on /a(?=b(?!cde/', '/a(?=b(?!cde/', Context.AllowRegExp);
fail('fails on /a(', '/(', Context.AllowRegExp);
fail('fails on /(', '/(', Context.AllowRegExp);
fail('fails on /(?=b(?!cde/', '/(?=b(?!cde/', Context.AllowRegExp);
fail('fails on /[abc\\udeff', '/[abc\\udeff', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/፰', Context.AllowRegExp);
fail('fails on /i/gg', '/i/gg', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ii', Context.AllowRegExp);
fail('fails on /i/mm', '/i/mm', Context.AllowRegExp);
fail('fails on /i/uu', '/i/uu', Context.AllowRegExp);
fail('fails on /i/yy', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ss', '/i/ss', Context.AllowRegExp);
fail('fails on /i/dd', '/i/dd', Context.AllowRegExp);
fail('fails on /i/a', '/i/a', Context.AllowRegExp);
fail('fails on /i/፰', '/i/፰', Context.AllowRegExp);
});

0 comments on commit 4174428

Please sign in to comment.