From 671dc573cf5046fdf828bb955770561e380f2e16 Mon Sep 17 00:00:00 2001 From: Kenny F Date: Fri, 9 Aug 2019 12:13:54 +0800 Subject: [PATCH] fix(parser): avoid reinterpretation to pattern if not needed --- src/estree.ts | 11 +- src/parser.ts | 363 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 284 insertions(+), 90 deletions(-) diff --git a/src/estree.ts b/src/estree.ts index 6ea35bad..d1fb1898 100644 --- a/src/estree.ts +++ b/src/estree.ts @@ -54,7 +54,7 @@ export type Node = | BlockStatement | BreakStatement | CallExpression - | OptionalChain + | OptionalExpression | ImportExpression | CatchClause | ClassBody @@ -160,6 +160,7 @@ export type Expression = | BinaryExpression | ConditionalExpression | MetaProperty + | OptionalExpression | JSXClosingElement | JSXClosingFragment | JSXExpressionContainer @@ -185,7 +186,7 @@ export type JSXExpression = JSXEmptyExpression | JSXSpreadChild | JSXExpressionC export type JSXTagNameExpression = JSXIdentifier | JSXMemberExpression | JSXNamespacedName; export type LeftHandSideExpression = | CallExpression - | OptionalChain + | OptionalExpression | ImportExpression | ClassExpression | ClassDeclaration @@ -357,9 +358,9 @@ export interface ImportExpression extends _Node { source: Expression; } -export interface OptionalChain extends _Node { - type: 'OptionalChain'; - expression: MemberExpression | CallExpression | Identifier | OptionalChain; +export interface OptionalExpression extends _Node { + type: 'OptionalExpression'; + expression: any; } export interface CallExpression extends _Node { diff --git a/src/parser.ts b/src/parser.ts index 34f203f1..0446eaa5 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -742,7 +742,7 @@ export function parseExpressionOrLabelledStatement( * */ - expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression); + expr = parseAssignmentExpression(parser, context, 0, 0, start, line, column, expr as ESTree.ArgumentExpression); /** Sequence expression * @@ -1111,7 +1111,7 @@ export function parseAsyncArrowOrAsyncFunctionDeclaration( * 2. LeftHandSideExpression = AssignmentExpression * */ - expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression); + expr = parseAssignmentExpression(parser, context, 0, 0, start, line, column, expr as ESTree.ArgumentExpression); parser.assignable = AssignmentKind.Assignable; @@ -1153,7 +1153,7 @@ export function parseDirective( expression = parseMemberOrUpdateExpression(parser, context, expression, 0, 0, 0, start, line, column); if (parser.token !== Token.Semicolon) { - expression = parseAssignmentExpression(parser, context, 0, start, line, column, expression); + expression = parseAssignmentExpression(parser, context, 0, 0, start, line, column, expression); if (parser.token === Token.Comma) { expression = parseSequenceExpression(parser, context, 0, start, line, column, expression); @@ -1915,7 +1915,7 @@ export function parseLetIdentOrVarDeclarationStatement( * 2. LeftHandSideExpression = AssignmentExpression * */ - expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression); + expr = parseAssignmentExpression(parser, context, 0, 0, start, line, column, expr as ESTree.ArgumentExpression); } /** Sequence expression @@ -2227,6 +2227,7 @@ export function parseForStatement( void 0, 1, 0, + 0, BindingKind.Empty, Origin.ForStatement, tokenPos, @@ -2239,6 +2240,7 @@ export function parseForStatement( void 0, 1, 0, + 0, BindingKind.Empty, Origin.ForStatement, tokenPos, @@ -2326,7 +2328,7 @@ export function parseForStatement( report(parser, Errors.CantAssignToInOfForLoop, 'loop'); } - init = parseAssignmentExpression(parser, context | Context.DisallowIn, 0, tokenPos, linePos, colPos, init); + init = parseAssignmentExpression(parser, context | Context.DisallowIn, 0, 0, tokenPos, linePos, colPos, init); } if (parser.token === Token.Comma) @@ -2639,7 +2641,7 @@ export function parseImportMetaDeclaration( * 2. LeftHandSideExpression = AssignmentExpression */ - expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.Expression); + expr = parseAssignmentExpression(parser, context, 0, 0, start, line, column, expr as ESTree.Expression); /** * ExpressionStatement[Yield, Await]: @@ -2814,6 +2816,7 @@ function parseExportDeclaration( parser, context, 0, + 0, tokenPos, linePos, colPos, @@ -3114,7 +3117,7 @@ export function parseExpression( expr = parseMemberOrUpdateExpression(parser, context, expr, inGroup, 0, 0, start, line, column); - return parseAssignmentExpression(parser, context, inGroup, start, line, column, expr); + return parseAssignmentExpression(parser, context, inGroup, 0, start, line, column, expr); } /** @@ -3180,6 +3183,7 @@ export function parseAssignmentExpression( parser: ParserState, context: Context, inGroup: 0 | 1, + isPattern: 0 | 1, start: number, line: number, column: number, @@ -3201,7 +3205,7 @@ export function parseAssignmentExpression( report(parser, Errors.CantAssignTo); } if ( - (token === Token.Assign && (left.type as string) === 'ArrayExpression') || + (!isPattern && (token === Token.Assign && (left.type as string) === 'ArrayExpression')) || (left.type as string) === 'ObjectExpression' ) { reinterpretToPattern(parser, left); @@ -3211,12 +3215,25 @@ export function parseAssignmentExpression( const right = parseExpression(parser, context, 1, 1, inGroup, parser.tokenPos, parser.linePos, parser.colPos); - left = finishNode(parser, context, start, line, column, { - type: 'AssignmentExpression', - left, - operator: KeywordDescTable[token & Token.Type], - right - }); + left = finishNode( + parser, + context, + start, + line, + column, + isPattern + ? { + type: 'AssignmentPattern', + left, + right + } + : ({ + type: 'AssignmentExpression', + left, + operator: KeywordDescTable[token & Token.Type], + right + } as any) + ); parser.assignable = AssignmentKind.CannotAssign; @@ -3419,7 +3436,7 @@ export function parseAsyncExpression( start: number, line: number, column: number -): any { +): ESTree.FunctionExpression | ESTree.ArrowFunctionExpression | ESTree.CallExpression | ESTree.Identifier { const { token } = parser; const expr = parseIdentifier(parser, context, isPattern); const { flags } = parser; @@ -3933,7 +3950,7 @@ export function parseOptionalExpression( parser: ParserState, context: Context, expr: ESTree.Expression -): ESTree.OptionalChain { +): ESTree.OptionalExpression { // OptionalExpression :: // MemberExpression // CallExpression @@ -3942,7 +3959,7 @@ export function parseOptionalExpression( return finishNode(parser, context, tokenPos, linePos, colPos, { type: 'OptionalExpression', expression: expr - } as any); + }); } /** @@ -4864,6 +4881,7 @@ function parseArrayLiteral( void 0, skipInitializer, inGroup, + 0, BindingKind.Empty, Origin.None, start, @@ -4897,6 +4915,7 @@ export function parseArrayExpressionOrPattern( scope: ScopeState | undefined, skipInitializer: 0 | 1, inGroup: 0 | 1, + isPattern: 0 | 1, kind: BindingKind, origin: Origin, start: number, @@ -4984,12 +5003,25 @@ export function parseArrayExpressionOrPattern( const right = parseExpression(parser, context, 1, 1, inGroup, parser.tokenPos, parser.linePos, parser.colPos); - left = finishNode(parser, context, tokenPos, linePos, colPos, { - type: 'AssignmentExpression', - operator: '=', - left, - right - }); + left = finishNode( + parser, + context, + tokenPos, + linePos, + colPos, + isPattern + ? { + type: 'AssignmentPattern', + left, + right + } + : ({ + type: 'AssignmentExpression', + operator: '=', + left, + right + } as any) + ); destructible |= parser.destructible & DestructuringKind.Yield @@ -5009,7 +5041,7 @@ export function parseArrayExpressionOrPattern( if (parser.token !== Token.Comma && parser.token !== Token.RightBracket) { if (parser.token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; - left = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, left); + left = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, left); } else if (parser.token !== Token.Assign) { destructible |= parser.assignable & AssignmentKind.CannotAssign @@ -5020,13 +5052,26 @@ export function parseArrayExpressionOrPattern( } else if (token & Token.IsPatternStart) { left = parser.token === Token.LeftBrace - ? parseObjectLiteralOrPattern(parser, context, scope, 0, inGroup, kind, origin, tokenPos, linePos, colPos) + ? parseObjectLiteralOrPattern( + parser, + context, + scope, + 0, + inGroup, + isPattern, + kind, + origin, + tokenPos, + linePos, + colPos + ) : parseArrayExpressionOrPattern( parser, context, scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -5052,7 +5097,7 @@ export function parseArrayExpressionOrPattern( destructible = parser.assignable & AssignmentKind.CannotAssign ? DestructuringKind.CannotDestruct : 0; if (parser.token !== Token.Comma && parser.token !== Token.RightBracket) { - left = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, left); + left = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, left); } else if (parser.token !== Token.Assign) { destructible |= parser.assignable & AssignmentKind.CannotAssign @@ -5070,6 +5115,7 @@ export function parseArrayExpressionOrPattern( origin, 0, inGroup, + isPattern, tokenPos, linePos, colPos @@ -5081,7 +5127,7 @@ export function parseArrayExpressionOrPattern( left = parseLeftHandSideExpression(parser, context, 1, 0, tokenPos, linePos, colPos); if (parser.token !== Token.Comma && parser.token !== Token.RightBracket) { - left = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, left); + left = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, left); if ((kind & (BindingKind.Empty | BindingKind.ArgumentList)) < 1 && token === Token.LeftParen) destructible |= DestructuringKind.CannotDestruct; } else if (parser.assignable & AssignmentKind.CannotAssign) { @@ -5105,12 +5151,22 @@ export function parseArrayExpressionOrPattern( consume(parser, context, Token.RightBracket); const node = finishNode(parser, context, start, line, column, { - type: 'ArrayExpression', + type: isPattern ? 'ArrayPattern' : 'ArrayExpression', elements - }); + } as any); if (!skipInitializer && parser.token & Token.IsAssignOp) { - return parseArrayOrObjectAssignmentPattern(parser, context, destructible, inGroup, start, line, column, node); + return parseArrayOrObjectAssignmentPattern( + parser, + context, + destructible, + inGroup, + isPattern, + start, + line, + column, + node + ); } parser.destructible = destructible; @@ -5136,6 +5192,7 @@ function parseArrayOrObjectAssignmentPattern( context: Context, destructible: AssignmentKind | DestructuringKind, inGroup: 0 | 1, + isPattern: 0 | 1, start: number, line: number, column: number, @@ -5166,12 +5223,25 @@ function parseArrayOrObjectAssignmentPattern( (parser.destructible & DestructuringKind.Await ? DestructuringKind.Await : 0) | (parser.destructible & DestructuringKind.Yield ? DestructuringKind.Yield : 0); - return finishNode(parser, context, start, line, column, { - type: 'AssignmentExpression', - left: node, - operator: '=', - right - }); + return finishNode( + parser, + context, + start, + line, + column, + isPattern + ? { + type: 'AssignmentPattern', + left: node, + right + } + : ({ + type: 'AssignmentExpression', + left: node, + operator: '=', + right + } as any) + ); } /** @@ -5197,6 +5267,7 @@ function parseSpreadElement( origin: Origin, isAsync: 0 | 1, inGroup: 0 | 1, + isPattern: 0 | 1, start: number, line: number, column: number @@ -5237,6 +5308,7 @@ function parseSpreadElement( parser, context, inGroup, + isPattern, tokenPos, linePos, colPos, @@ -5258,8 +5330,32 @@ function parseSpreadElement( } else if (token & Token.IsPatternStart) { argument = parser.token === Token.LeftBrace - ? parseObjectLiteralOrPattern(parser, context, scope, 1, inGroup, kind, origin, tokenPos, linePos, colPos) - : parseArrayExpressionOrPattern(parser, context, scope, 1, inGroup, kind, origin, tokenPos, linePos, colPos); + ? parseObjectLiteralOrPattern( + parser, + context, + scope, + 1, + inGroup, + isPattern, + kind, + origin, + tokenPos, + linePos, + colPos + ) + : parseArrayExpressionOrPattern( + parser, + context, + scope, + 1, + inGroup, + isPattern, + kind, + origin, + tokenPos, + linePos, + colPos + ); token = parser.token; @@ -5276,6 +5372,7 @@ function parseSpreadElement( parser, context, inGroup, + isPattern, tokenPos, linePos, colPos, @@ -5307,6 +5404,7 @@ function parseSpreadElement( parser, context, inGroup, + isPattern, tokenPos, linePos, colPos, @@ -5322,6 +5420,7 @@ function parseSpreadElement( parser, context, inGroup, + isPattern, tokenPos, linePos, colPos, @@ -5338,9 +5437,9 @@ function parseSpreadElement( if (parser.token !== closingToken && parser.token !== Token.Comma) report(parser, Errors.UnclosedSpreadElement); return finishNode(parser, context, start, line, column, { - type: 'SpreadElement', + type: isPattern ? 'RestElement' : 'SpreadElement', argument: argument as ESTree.SpreadArgument - }); + } as any); } if (parser.token !== closingToken) { @@ -5354,12 +5453,25 @@ function parseSpreadElement( const right = parseExpression(parser, context, 1, 1, inGroup, parser.tokenPos, parser.linePos, parser.colPos); - argument = finishNode(parser, context, tokenPos, linePos, colPos, { - type: 'AssignmentExpression', - left: argument as ESTree.SpreadArgument, - operator: '=', - right - }); + argument = finishNode( + parser, + context, + tokenPos, + linePos, + colPos, + isPattern + ? { + type: 'AssignmentPattern', + left: argument as ESTree.SpreadArgument, + right + } + : ({ + type: 'AssignmentExpression', + left: argument as ESTree.SpreadArgument, + operator: '=', + right + } as any) + ); destructible = DestructuringKind.CannotDestruct; } else { @@ -5371,9 +5483,9 @@ function parseSpreadElement( parser.destructible = destructible; return finishNode(parser, context, start, line, column, { - type: 'SpreadElement', + type: isPattern ? 'RestElement' : 'SpreadElement', argument: argument as ESTree.SpreadArgument - }); + } as any); } /** @@ -5491,6 +5603,7 @@ function parseObjectLiteral( void 0, skipInitializer, inGroup, + 0, BindingKind.Empty, Origin.None, start, @@ -5528,6 +5641,7 @@ export function parseObjectLiteralOrPattern( scope: ScopeState | undefined, skipInitializer: 0 | 1, inGroup: 0 | 1, + isPattern: 0 | 1, kind: BindingKind, origin: Origin, start: number, @@ -5599,6 +5713,7 @@ export function parseObjectLiteralOrPattern( origin, 0, inGroup, + isPattern, tokenPos, linePos, colPos @@ -5615,8 +5730,8 @@ export function parseObjectLiteralOrPattern( if (parser.token === Token.Comma || parser.token === Token.RightBrace || parser.token === Token.Assign) { state |= PropertyKind.Shorthand; - if ((token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments) { - if (context & Context.Strict) destructible |= DestructuringKind.CannotDestruct; + if (context & Context.Strict && (token & Token.IsEvalOrArguments) === Token.IsEvalOrArguments) { + destructible |= DestructuringKind.CannotDestruct; } else { validateBindingIdentifier(parser, context, kind, token, 0); } @@ -5691,10 +5806,10 @@ export function parseObjectLiteralOrPattern( } else if (scope) { addVarOrBlock(parser, context, scope, valueAfterColon, kind, origin); } - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } else { destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } } else if ((parser.token & Token.IsPatternStart) === Token.IsPatternStart) { value = @@ -5705,6 +5820,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -5717,6 +5833,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -5741,7 +5858,16 @@ export function parseObjectLiteralOrPattern( const { token } = parser; if (token !== Token.Comma && token !== Token.RightBrace) { - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression( + parser, + context, + inGroup, + isPattern, + tokenPos, + linePos, + colPos, + value + ); if (token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; } else if (token !== Token.Assign) { @@ -5769,7 +5895,16 @@ export function parseObjectLiteralOrPattern( const { token } = parser; if (token !== Token.Comma && token !== Token.RightBrace) { - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, tokenPos, colPos, value); + value = parseAssignmentExpression( + parser, + context, + inGroup, + isPattern, + tokenPos, + tokenPos, + colPos, + value + ); if (token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; } } @@ -5918,10 +6053,10 @@ export function parseObjectLiteralOrPattern( } } else if (parser.token === Token.Assign) { if (parser.assignable & AssignmentKind.CannotAssign) destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } else { destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } } else if ((parser.token & Token.IsPatternStart) === Token.IsPatternStart) { value = @@ -5932,6 +6067,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -5944,6 +6080,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -5969,10 +6106,10 @@ export function parseObjectLiteralOrPattern( parser, context, inGroup, + isPattern, tokenPos, linePos, colPos, - value ); } else if (parser.token !== Token.Assign) { @@ -6001,7 +6138,16 @@ export function parseObjectLiteralOrPattern( if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) { if (parser.token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression( + parser, + context, + inGroup, + isPattern, + tokenPos, + linePos, + colPos, + value + ); } } } @@ -6059,10 +6205,10 @@ export function parseObjectLiteralOrPattern( : token === Token.Assign ? 0 : DestructuringKind.Assignable; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } else { destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression(parser, context, inGroup, isPattern, tokenPos, linePos, colPos, value); } } else if ((parser.token & Token.IsPatternStart) === Token.IsPatternStart) { value = @@ -6073,6 +6219,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -6085,6 +6232,7 @@ export function parseObjectLiteralOrPattern( scope, 0, inGroup, + isPattern, kind, origin, tokenPos, @@ -6109,7 +6257,16 @@ export function parseObjectLiteralOrPattern( if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) { if (parser.token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression( + parser, + context, + inGroup, + isPattern, + tokenPos, + linePos, + colPos, + value + ); } else if (parser.token !== Token.Assign) { destructible |= parser.assignable & AssignmentKind.CannotAssign @@ -6134,7 +6291,16 @@ export function parseObjectLiteralOrPattern( if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) { if (parser.token !== Token.Assign) destructible |= DestructuringKind.CannotDestruct; - value = parseAssignmentExpression(parser, context, inGroup, tokenPos, linePos, colPos, value); + value = parseAssignmentExpression( + parser, + context, + inGroup, + isPattern, + tokenPos, + linePos, + colPos, + value + ); } } } @@ -6235,12 +6401,22 @@ export function parseObjectLiteralOrPattern( if (prototypeCount > 1) destructible |= DestructuringKind.SeenProto; const node = finishNode(parser, context, start, line, column, { - type: 'ObjectExpression', + type: isPattern ? 'ObjectPattern' : 'ObjectExpression', properties - }); + } as any); if (!skipInitializer && parser.token & Token.IsAssignOp) { - return parseArrayOrObjectAssignmentPattern(parser, context, destructible, inGroup, start, line, column, node); + return parseArrayOrObjectAssignmentPattern( + parser, + context, + destructible, + inGroup, + isPattern, + start, + line, + column, + node + ); } parser.destructible = destructible; @@ -6293,7 +6469,7 @@ export function parseMethodFormals( report(parser, Errors.BadSetterRestParameter); } - while (parser.token !== Token.RightParen) { + while (parser.token !== Token.Comma) { let left: ESTree.BindingName | ESTree.SpreadElement | ESTree.AssignmentPattern | null = null; const { tokenPos, tokenValue, linePos, colPos } = parser; if (parser.token & Token.IsIdentifier) { @@ -6304,7 +6480,6 @@ export function parseMethodFormals( ) { parser.flags |= Flags.SimpleParameterList; } - if (scope && (parser.token & Token.IsIdentifier) === Token.IsIdentifier) { addVarOrBlock(parser, context, scope, tokenValue, BindingKind.ArgumentList, Origin.None); } @@ -6317,6 +6492,7 @@ export function parseMethodFormals( scope, 1, inGroup, + 1, type, Origin.None, tokenPos, @@ -6330,6 +6506,7 @@ export function parseMethodFormals( scope, 1, inGroup, + 1, type, Origin.None, tokenPos, @@ -6346,6 +6523,7 @@ export function parseMethodFormals( Origin.None, 0, inGroup, + 1, tokenPos, linePos, colPos @@ -6354,8 +6532,6 @@ export function parseMethodFormals( parser.flags |= Flags.SimpleParameterList; - reinterpretToPattern(parser, left); - if (parser.destructible & (DestructuringKind.Assignable | DestructuringKind.CannotDestruct)) report(parser, Errors.InvalidBindingDestruct); } @@ -6377,7 +6553,11 @@ export function parseMethodFormals( setterArgs++; params.push(left as any); - if (parser.token !== Token.RightParen) consume(parser, context, Token.Comma); + if (!consumeOpt(parser, context, Token.Comma)) break; + if (parser.token === Token.RightParen) { + // allow the trailing comma + break; + } } if (kind & PropertyKind.Setter && setterArgs !== 1) { @@ -6491,7 +6671,7 @@ export function parseParenthesizedExpression( expr = parseMemberOrUpdateExpression(parser, context, expr, /* inGroup */ 1, 0, 0, tokenPos, linePos, colPos); if (parser.token !== Token.RightParen && parser.token !== Token.Comma) { - expr = parseAssignmentExpression(parser, context, 1, tokenPos, linePos, colPos, expr); + expr = parseAssignmentExpression(parser, context, 1, 0, tokenPos, linePos, colPos, expr); } } } else if ((token & Token.IsPatternStart) === Token.IsPatternStart) { @@ -6503,6 +6683,7 @@ export function parseParenthesizedExpression( scope, 0, 1, + 0, kind, origin, tokenPos, @@ -6515,6 +6696,7 @@ export function parseParenthesizedExpression( scope, 0, 1, + 0, kind, origin, tokenPos, @@ -6536,7 +6718,7 @@ export function parseParenthesizedExpression( destructible |= DestructuringKind.CannotDestruct; if (parser.token !== Token.RightParen && parser.token !== Token.Comma) { - expr = parseAssignmentExpression(parser, context, 0, tokenPos, linePos, colPos, expr); + expr = parseAssignmentExpression(parser, context, 0, 0, tokenPos, linePos, colPos, expr); } } } else if (token === Token.Ellipsis) { @@ -6549,6 +6731,7 @@ export function parseParenthesizedExpression( origin, 0, 1, + 0, tokenPos, linePos, colPos @@ -6903,13 +7086,18 @@ export function parseFormalParametersOrFormalList( parser.flags = (parser.flags | Flags.SimpleParameterList) ^ Flags.SimpleParameterList; - context = (context | Context.DisallowIn) ^ Context.DisallowIn; - const params: ESTree.Parameter[] = []; + if (parser.token === Token.RightParen) { + nextToken(parser, context); + return params; + } + + context = (context | Context.DisallowIn) ^ Context.DisallowIn; + let isSimpleParameterList: 0 | 1 = 0; - while (parser.token !== Token.RightParen) { + while (parser.token !== Token.Comma) { let left: any; const { tokenPos, tokenValue, linePos, colPos } = parser; if (parser.token & Token.IsIdentifier) { @@ -6936,6 +7124,7 @@ export function parseFormalParametersOrFormalList( scope, 1, inGroup, + 1, kind, Origin.None, tokenPos, @@ -6949,6 +7138,7 @@ export function parseFormalParametersOrFormalList( scope, 1, inGroup, + 1, kind, Origin.None, tokenPos, @@ -6965,6 +7155,7 @@ export function parseFormalParametersOrFormalList( Origin.None, 0, inGroup, + 1, tokenPos, linePos, colPos @@ -6975,8 +7166,6 @@ export function parseFormalParametersOrFormalList( isSimpleParameterList = 1; - reinterpretToPattern(parser, left); - if (parser.destructible & (DestructuringKind.Assignable | DestructuringKind.CannotDestruct)) { report(parser, Errors.InvalidBindingDestruct); } @@ -6998,7 +7187,11 @@ export function parseFormalParametersOrFormalList( params.push(left); - if (parser.token !== Token.RightParen) consume(parser, context, Token.Comma); + if (!consumeOpt(parser, context, Token.Comma)) break; + if (parser.token === Token.RightParen) { + // allow the trailing comma + break; + } } if (isSimpleParameterList) parser.flags |= Flags.SimpleParameterList; @@ -7372,14 +7565,14 @@ export function parseAsyncArrowOrCallExpression( ); if (parser.token !== Token.RightParen && parser.token !== Token.Comma) { - expr = parseAssignmentExpression(parser, context, 1, tokenPos, linePos, colPos, expr as ESTree.Expression); + expr = parseAssignmentExpression(parser, context, 1, 0, tokenPos, linePos, colPos, expr as ESTree.Expression); } } } else if (token & Token.IsPatternStart) { expr = token === Token.LeftBrace - ? parseObjectLiteralOrPattern(parser, context, scope, 0, 1, kind, origin, tokenPos, linePos, colPos) - : parseArrayExpressionOrPattern(parser, context, scope, 0, 1, kind, origin, tokenPos, linePos, colPos); + ? parseObjectLiteralOrPattern(parser, context, scope, 0, 1, 0, kind, origin, tokenPos, linePos, colPos) + : parseArrayExpressionOrPattern(parser, context, scope, 0, 1, 0, kind, origin, tokenPos, linePos, colPos); destructible |= parser.destructible; @@ -7408,6 +7601,7 @@ export function parseAsyncArrowOrCallExpression( origin, 1, 1, + 0, tokenPos, linePos, colPos @@ -8185,6 +8379,7 @@ export function parseFieldDefinition( parser, context | Context.InClass, 0, + 0, tokenPos, linePos, colPos, @@ -8237,10 +8432,8 @@ export function parseBindingPattern( const left = parser.token === Token.LeftBracket - ? parseArrayExpressionOrPattern(parser, context, scope, 1, 0, type, origin, start, line, column) - : parseObjectLiteralOrPattern(parser, context, scope, 1, 0, type, origin, start, line, column); - - reinterpretToPattern(parser, left); + ? parseArrayExpressionOrPattern(parser, context, scope, 1, 0, 1, type, origin, start, line, column) + : parseObjectLiteralOrPattern(parser, context, scope, 1, 0, 1, type, origin, start, line, column); if (parser.destructible & DestructuringKind.CannotDestruct) report(parser, Errors.InvalidBindingDestruct);