Skip to content

Commit

Permalink
fix(parser): minor refactoring & performance tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jun 5, 2019
1 parent db21faf commit 39dc0e7
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 164 deletions.
2 changes: 1 addition & 1 deletion src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ export const errorMessages: {
[Errors.InvalidImportTail]: 'Trailing comma is disallowed inside import(...) arguments',
[Errors.ImportNotOneArg]: 'import() requires exactly one argument',
[Errors.InvalidImportNew]: 'Cannot use new with import(...)',
[Errors.InvalidSpreadInImport]: '... is not allowed in import() '
[Errors.InvalidSpreadInImport]: '... is not allowed in import()'
};

export class ParseError extends SyntaxError {
Expand Down
141 changes: 55 additions & 86 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2531,6 +2531,7 @@ export function parseUnaryExpression(
*/
export function parseYieldExpressionOrIdentifier(parser: ParserState, context: Context, start: number): any {
parser.flags |= Flags.Yield;

if (context & Context.InYieldContext) {
// YieldExpression[In] :
// yield
Expand Down Expand Up @@ -4817,52 +4818,35 @@ export function parseParenthesizedExpression(
while (parser.token !== Token.RightParen) {
const idxAfterLeftParen = parser.tokenIndex;

if (parser.token & (Token.IsIdentifier | Token.Keyword)) {
const { token } = parser;

if (
(token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments ||
(token & Token.FutureReserved) === Token.FutureReserved
) {
isComplex = 1;
}
const { token } = parser;

if (token & (Token.IsIdentifier | Token.Keyword)) {
expr = parsePrimaryExpressionExtended(parser, context, BindingType.None, 0, 1, 1, idxAfterLeftParen);

if (consumeOpt(parser, context | Context.AllowRegExp, Token.Assign)) {
if (parser.token === Token.Assign) {
isComplex = 1;

validateBindingIdentifier(parser, context, BindingType.None, token);

const right = parseExpression(parser, context, /* assignable */ 1, 1, parser.tokenIndex);

parser.assignable = AssignmentKind.CannotAssign;

expr = finishNode(parser, context, idxAfterLeftParen, {
type: 'AssignmentExpression',
left: expr,
operator: '=',
right
});
} else if ((parser.token & Token.IsCommaOrRightParen) === Token.IsCommaOrRightParen) {
if (parser.assignable & AssignmentKind.CannotAssign) {
destructible |= DestructuringKind.CannotDestruct;
isComplex = 1;
} else if (
(token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments ||
(token & Token.FutureReserved) === Token.FutureReserved
) {
isComplex = 1;
}
} else {
destructible |=
(parser.token & Token.IsCommaOrRightParen) === Token.IsCommaOrRightParen
? parser.assignable & AssignmentKind.CannotAssign
? DestructuringKind.CannotDestruct
: 0
: DestructuringKind.CannotDestruct;
destructible |= DestructuringKind.CannotDestruct;
}

expr = parseAssignmentExpression(
parser,
context,
1,
idxAfterLeftParen,
parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 1, idxAfterLeftParen)
);
if ((parser.token & Token.IsCommaOrRightParen) !== Token.IsCommaOrRightParen) {
expr = parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 1, idxAfterLeftParen);

expr = parseAssignmentExpression(parser, context, 1, idxAfterLeftParen, expr);
}
} else if (parser.token & Token.IsPatternStart) {
} else if (token & Token.IsPatternStart) {
expr =
parser.token === Token.LeftBrace
token === Token.LeftBrace
? parseObjectLiteralOrPattern(parser, context, 0, 1, BindingType.None, idxAfterLeftParen)
: parseArrayExpressionOrPattern(parser, context, 0, 1, BindingType.None, idxAfterLeftParen);

Expand All @@ -4883,7 +4867,7 @@ export function parseParenthesizedExpression(
expr = parseAssignmentExpression(parser, context, 0, idxAfterLeftParen, expr);
}
}
} else if (parser.token === Token.Ellipsis) {
} else if (token === Token.Ellipsis) {
expr = parseRestOrSpreadElement(
parser,
context,
Expand Down Expand Up @@ -5393,47 +5377,37 @@ export function parseAsyncArrowOrCallExpression(
const params: ESTree.Expression[] = [];

while (parser.token !== Token.RightParen) {
const idxAfterLeftParen = parser.tokenIndex;
if (parser.token & (Token.IsIdentifier | Token.Keyword)) {
if (
(parser.token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments ||
(parser.token & Token.FutureReserved) === Token.FutureReserved
) {
isComplex = 1;
}
const { token, tokenIndex } = parser;

expr = parsePrimaryExpressionExtended(parser, context, BindingType.None, 0, 1, 1, parser.tokenIndex);
if (token & (Token.IsIdentifier | Token.Keyword)) {
expr = parsePrimaryExpressionExtended(parser, context, BindingType.None, 0, 1, 1, tokenIndex);

if (consumeOpt(parser, context | Context.AllowRegExp, Token.Assign)) {
if (parser.token === Token.Assign) {
isComplex = 1;

const right = parseExpression(parser, context, /* assignable */ 1, 1, parser.tokenIndex);
parser.assignable = AssignmentKind.CannotAssign;
expr = finishNode(parser, context, idxAfterLeftParen, {
type: 'AssignmentExpression',
left: expr,
operator: '=',
right
});
} else if ((parser.token & Token.IsCommaOrRightParen) === Token.IsCommaOrRightParen) {
if (parser.assignable & AssignmentKind.CannotAssign) {
destructible |= DestructuringKind.CannotDestruct;
isComplex = 1;
} else if (
(token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments ||
(token & Token.FutureReserved) === Token.FutureReserved
) {
isComplex = 1;
}
} else {
destructible |=
(parser.token & Token.IsCommaOrRightParen) === Token.IsCommaOrRightParen
? parser.assignable & AssignmentKind.CannotAssign
? DestructuringKind.CannotDestruct
: 0
: DestructuringKind.CannotDestruct;

expr = parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 1, parser.tokenIndex);
destructible |= DestructuringKind.CannotDestruct;
}

expr = parseAssignmentExpression(parser, context, 1, parser.tokenIndex, expr);
if ((parser.token & Token.IsCommaOrRightParen) !== Token.IsCommaOrRightParen) {
expr = parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 1, tokenIndex);

destructible |= parser.assignable;
expr = parseAssignmentExpression(parser, context, 1, tokenIndex, expr);
}
} else if (parser.token & Token.IsPatternStart) {
} else if (token & Token.IsPatternStart) {
expr =
parser.token === Token.LeftBrace
? parseObjectLiteralOrPattern(parser, context, 0, 1, BindingType.None, idxAfterLeftParen)
: parseArrayExpressionOrPattern(parser, context, 0, 1, BindingType.None, idxAfterLeftParen);
token === Token.LeftBrace
? parseObjectLiteralOrPattern(parser, context, 0, 1, BindingType.None, tokenIndex)
: parseArrayExpressionOrPattern(parser, context, 0, 1, BindingType.None, tokenIndex);

destructible |= parser.destructible;

Expand All @@ -5444,38 +5418,29 @@ export function parseAsyncArrowOrCallExpression(
if ((parser.token & Token.IsCommaOrRightParen) !== Token.IsCommaOrRightParen) {
if (destructible & DestructuringKind.MustDestruct) report(parser, Errors.InvalidPatternTail);

expr = parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 0, idxAfterLeftParen);
expr = parseMemberOrUpdateExpression(parser, context, expr, /* assignable */ 0, 0, 0, tokenIndex);

destructible |= DestructuringKind.CannotDestruct;

if ((parser.token & Token.IsCommaOrRightParen) !== Token.IsCommaOrRightParen)
expr = parseAssignmentExpression(parser, context, 0, parser.tokenIndex, expr);
}
} else if (parser.token === Token.Ellipsis) {
expr = parseRestOrSpreadElement(
parser,
context,
Token.RightParen,
BindingType.ArgumentList,
1,
1,
idxAfterLeftParen
);
} else if (token === Token.Ellipsis) {
expr = parseRestOrSpreadElement(parser, context, Token.RightParen, BindingType.ArgumentList, 1, 1, tokenIndex);

destructible |= parser.destructible;

isComplex = 1;
if (parser.token !== Token.RightParen) parser.destructible |= DestructuringKind.CannotDestruct;
} else {
expr = parseExpression(parser, context, /* assignable */ 1, 0, idxAfterLeftParen);
expr = parseExpression(parser, context, /* assignable */ 1, 0, tokenIndex);

destructible = parser.assignable;

params.push(expr);

while (consumeOpt(parser, context | Context.AllowRegExp, Token.Comma)) {
params.push(parseExpression(parser, context, /* assignable */ 1, 0, idxAfterLeftParen));
parser.assignable = AssignmentKind.CannotAssign;
params.push(parseExpression(parser, context, /* assignable */ 1, 0, tokenIndex));
}

destructible |= parser.assignable;
Expand All @@ -5484,6 +5449,8 @@ export function parseAsyncArrowOrCallExpression(

parser.destructible = destructible | DestructuringKind.CannotDestruct;

parser.assignable = AssignmentKind.CannotAssign;

return finishNode(parser, context, start, {
type: 'CallExpression',
callee,
Expand Down Expand Up @@ -5519,6 +5486,8 @@ export function parseAsyncArrowOrCallExpression(
report(parser, Errors.InvalidShorthandPropInit);
}

parser.assignable = AssignmentKind.CannotAssign;

return finishNode(parser, context, start, {
type: 'CallExpression',
callee,
Expand Down
43 changes: 43 additions & 0 deletions test/parser/expressions/bigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,37 @@ describe('Expressions - BigInt', () => {
'var x = 2n ** 31n - 1n;',
'var x = kMaxInt - 32n - 2n;',
'x = [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n]',
'let x = 2n ** 30n - 1n;',
'let x = 2n ** 30n;',
'-4n',
'-9007199254740992n',
'(-9007199254740992n)',
'a(-b.c - 3n) === -9007199254740994n',
'1n + 1;',
'1n + Object(1);',
'1n + true;',
'1 & Object(1n)',
' NaN | 1n;',
'a(0b101n) << b(1n)',
'0n << 128n === 0n',
'0x246n << 127n === 0x12300000000000000000000000000000000n',
'0b101n << 1n === 0b1010n',
'0x246n << 0n === 0x246n',
'0x123456789abcdef0fedcba9876543212345678n << -128n, 0x123456n',
'-0x246n << 127n === -0x12300000000000000000000000000000000n',
'-0x123456789abcdef0fedcba9876543212345678n << 64n, -0x123456789abcdef0fedcba98765432123456780000000000000000n',
'-1n >>> -128n;',
'a(1, 3n), -1n;',
'a.b(BigInt(-9007199254740991), -9007199254740991n);',
'(("0xf", 0), 0xfn);',
'a(Number(0n), 0);',
'let {} = 0n;',
'() => 1n / 0n',
'a(1n != false);',
'() => 1n ** -1n',
'1n >= 1',
'a(0n <= 1);',
'a(1 <= 1n);',
`var data = [{
a: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e7n,
r: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e6n
Expand Down Expand Up @@ -94,6 +125,18 @@ describe('Expressions - BigInt', () => {
parseSource(`${arg}`, undefined, Context.OptionsWebCompat);
});
});

it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.None);
});
});

it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.Strict | Context.Module);
});
});
}

pass('Expressions - BigInt (pass)', [
Expand Down
6 changes: 5 additions & 1 deletion test/parser/expressions/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,11 @@ describe('Expressions - Group', () => {
['({a:for} = 0)', Context.None],
['({a: b += 0} = {})', Context.None],
['[a += b] = []', Context.None],
["({'a'} = 0)", Context.None],
['({"a"} = 0)', Context.None],
['"use strict"; (arguments = a)', Context.None],
['"use strict"; (arguments = a) => {}', Context.None],
['"use strict"; (arguments) => {}', Context.None],
['"use strict"; (a, arguments) => {}', Context.None],
['({var} = 0)', Context.None],
['({a.b} = 0)', Context.None],
['({0} = 0)', Context.None],
Expand Down

0 comments on commit 39dc0e7

Please sign in to comment.