Skip to content

Commit

Permalink
fix(parser): fixed a bunch of edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jul 24, 2019
1 parent c41a671 commit 1a100ba
Show file tree
Hide file tree
Showing 11 changed files with 530 additions and 66 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "meriyah",
"version": "1.4.1",
"version": "1.4.2",
"description": "A 100% compliant, self-hosted javascript parser with high focus on both performance and stability",
"main": "dist/meriyah.umd.js",
"module": "dist/meriyah.esm.js",
Expand Down
25 changes: 21 additions & 4 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ export function addVarName(

const hashed = '#' + name;
const isLexicalBinding = (type & BindingKind.LexicalBinding) !== 0;
const isWebCompat = context & Context.OptionsWebCompat && (context & Context.Strict) === 0
const isWebCompat = context & Context.OptionsWebCompat && (context & Context.Strict) === 0;

let currentScope: any = scope;

Expand Down Expand Up @@ -577,6 +577,23 @@ export function addVarName(
}
}

export function addVarOrBlock(parser: ParserState,
context: Context,
scope: any,
name: string,
type: BindingKind,
origin: BindingOrigin) {
if (type & BindingKind.Variable) {
addVarName(parser, context, scope, name, type);
} else {
addBlockName(parser, context, scope, name, type, BindingOrigin.Other);
}
if (origin & BindingOrigin.Export) {
updateExportsList(parser, parser.tokenValue);
addBindingToExports(parser, parser.tokenValue);
}
}

export function addBlockName(
parser: ParserState,
context: Context,
Expand Down Expand Up @@ -628,10 +645,10 @@ export function addBlockName(
while (currentScope && (currentScope.type & ScopeKind.FuncRoot) !== ScopeKind.FuncRoot) {
const value = currentScope[hashed];
if (currentScope.type & ScopeKind.ArrowParams) {
if (value & BindingKind.EmptyBinding && (type & BindingKind.CatchIdentifierOrPattern) === 0 ) {
if (value && (value & BindingKind.EmptyBinding) === 0 && (type & BindingKind.CatchIdentifierOrPattern) === 0 ) {
report(parser, Errors.DuplicateBinding, name);
} else if (type & BindingKind.ArgumentList) {
currentScope.dupeParamErrorToken = recordScopeError(parser, Errors.Unexpected);
} else if (type & BindingKind.ArgumentList) {
currentScope.scopeError = recordScopeError(parser, Errors.Unexpected);
}
}
currentScope = currentScope.parent;
Expand Down
2 changes: 1 addition & 1 deletion src/meriyah.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export function parse(source: string, options?: Options): ESTree.Program {
export { ESTree, Options };

// Export current version
export const version = '1.4.1';
export const version = '1.4.2';
99 changes: 40 additions & 59 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
updateExportsList,
isEqualTagName,
isValidStrictMode,
createArrowScope
createArrowScope,
addVarOrBlock
} from './common';

/**
Expand Down Expand Up @@ -1856,37 +1857,35 @@ export function parseLetIdentOrVarDeclarationStatement(

parser.flags = (parser.flags | Flags.SimpleParameterList) ^ Flags.SimpleParameterList;

expr = parseArrowFunctionExpression(parser, context, scope, [expr], /* isAsync */ 0, start, line, column) as any;

return parseExpressionStatement(parser, context, expr, start, line, column);
expr = parseArrowFunctionExpression(parser, context, scope, [expr], /* isAsync */ 0, start, line, column);
} else {
/**
* UpdateExpression ::
* ('++' | '--')? LeftHandSideExpression
*
* MemberExpression ::
* (PrimaryExpression | FunctionLiteral | ClassLiteral)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* CallExpression ::
* (SuperCall | ImportCall)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* LeftHandSideExpression ::
* (NewExpression | MemberExpression) ...
*/

expr = parseMemberOrUpdateExpression(parser, context, expr, 0, start, line, column);

/**
* AssignmentExpression :
* 1. ConditionalExpression
* 2. LeftHandSideExpression = AssignmentExpression
*
*/
expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression);
}

/**
* UpdateExpression ::
* ('++' | '--')? LeftHandSideExpression
*
* MemberExpression ::
* (PrimaryExpression | FunctionLiteral | ClassLiteral)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* CallExpression ::
* (SuperCall | ImportCall)
* ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
*
* LeftHandSideExpression ::
* (NewExpression | MemberExpression) ...
*/

expr = parseMemberOrUpdateExpression(parser, context, expr, 0, start, line, column);

/**
* AssignmentExpression :
* 1. ConditionalExpression
* 2. LeftHandSideExpression = AssignmentExpression
*
*/
expr = parseAssignmentExpression(parser, context, 0, start, line, column, expr as ESTree.ArgumentExpression);

/** Sequence expression
*/
if (parser.token === Token.Comma) {
Expand All @@ -1906,6 +1905,7 @@ export function parseLetIdentOrVarDeclarationStatement(
const declarations = parseVariableDeclarationList(parser, context, scope, BindingKind.Let, BindingOrigin.Statement);

matchOrInsertSemicolon(parser, context | Context.AllowRegExp);

return finishNode(parser, context, start, line, column, {
type: 'VariableDeclaration',
kind: 'let',
Expand Down Expand Up @@ -4683,7 +4683,7 @@ export function parseArrayExpressionOrPattern(
if (parser.assignable & AssignmentKind.NotAssignable) {
reportMessageAt(parser.index, parser.line, parser.index - 3, Errors.CantAssignTo);
} else if (scope) {
addVarName(parser, context, scope, tokenValue, type);
addVarOrBlock(parser, context, scope, tokenValue, type, origin);
}
const right = parseExpression(parser, context, 1, 1, inGroup, parser.tokenPos, parser.linePos, parser.colPos);

Expand All @@ -4697,11 +4697,7 @@ export function parseArrayExpressionOrPattern(
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.CannotDestruct;
} else if (scope) {
addVarName(parser, context, scope, tokenValue, type);
if (origin & BindingOrigin.Export) {
updateExportsList(parser, tokenValue);
addBindingToExports(parser, tokenValue);
}
addVarOrBlock(parser, context, scope, tokenValue, type, origin);
}
} else {
destructible |=
Expand Down Expand Up @@ -5318,13 +5314,8 @@ export function parseObjectLiteralOrPattern(
validateBindingIdentifier(parser, context, type, token, 0);
}

if (scope) {
addVarName(parser, context, scope, tokenValue, type);
if (origin & BindingOrigin.Export) {
updateExportsList(parser, tokenValue);
addBindingToExports(parser, tokenValue);
}
}
if (scope) addVarOrBlock(parser, context, scope, tokenValue, type, origin);

if (consumeOpt(parser, context | Context.AllowRegExp, Token.Assign)) {
destructible |= DestructuringKind.MustDestruct;

Expand Down Expand Up @@ -5398,7 +5389,7 @@ export function parseObjectLiteralOrPattern(
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.CannotDestruct;
} else if (scope && (tokenAfterColon & Token.IsIdentifier) === Token.IsIdentifier) {
addVarName(parser, context, scope, valueAfterColon, type);
addVarOrBlock(parser, context, scope, valueAfterColon, type, origin);
}
} else {
destructible |=
Expand All @@ -5412,7 +5403,7 @@ export function parseObjectLiteralOrPattern(
} else if (token !== Token.Assign) {
destructible |= DestructuringKind.AssignableDestruct;
} else if (scope) {
addVarName(parser, context, scope, valueAfterColon, type);
addVarOrBlock(parser, context, scope, valueAfterColon, type, origin);
}
value = parseAssignmentExpression(
parser,
Expand Down Expand Up @@ -5713,7 +5704,7 @@ export function parseObjectLiteralOrPattern(
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.CannotDestruct;
} else if (scope) {
addVarName(parser, context, scope, tv, type);
addVarOrBlock(parser, context, scope, tv, type, origin);
}
} else {
destructible |=
Expand Down Expand Up @@ -5894,7 +5885,7 @@ export function parseObjectLiteralOrPattern(
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.CannotDestruct;
} else if (scope && (tokenAfterColon & Token.IsIdentifier) === Token.IsIdentifier) {
addVarName(parser, context, scope, tokenValue, type);
addVarOrBlock(parser, context, scope, tokenValue, type, origin);
}
} else {
destructible |=
Expand Down Expand Up @@ -6772,7 +6763,7 @@ export function parseFormalParametersOrFormalList(
}
}

if (scope && (parser.token & Token.IsIdentifier) === Token.IsIdentifier) {
if (scope) {
// Strict-mode disallows duplicate args. We may not know whether we are
// in strict mode or not (since the function body hasn't been parsed).
// In such cases the potential error will be saved on the parser object
Expand Down Expand Up @@ -8138,18 +8129,8 @@ export function parseBindingPattern(
// ObjectLiteral

if (parser.token & Token.IsIdentifier) {
if (scope) {
if (type & BindingKind.Variable) {
addVarName(parser, context, scope, parser.tokenValue, type);
} else {
addBlockName(parser, context, scope, parser.tokenValue, type, BindingOrigin.Other);
}
if (scope) addVarOrBlock(parser, context, scope, parser.tokenValue, type, origin);

if (origin & BindingOrigin.Export) {
updateExportsList(parser, parser.tokenValue);
addBindingToExports(parser, parser.tokenValue);
}
}
return parseAndClassifyIdentifier(parser, context, type, start, line, column);
}

Expand Down

0 comments on commit 1a100ba

Please sign in to comment.