Skip to content

Commit

Permalink
fix(parser): now unsets 'SimpleParameterList' masks correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed May 15, 2019
1 parent 9854a83 commit f48b486
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ A 100% compliant, self-hosted javascript parser with high focus on both performa
* Emits an ESTree-compatible abstract syntax tree.
* No backtracking
* Reduced memory usage
* Very well tested (~68k unit tests with full code coverage))
* Very well tested (~71k unit tests with full code coverage))
* Lightweight - ~71 KB minified

## ESNext features
Expand Down
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": "0.1.6",
"version": "0.1.7",
"description": "Fast and lightweight, standard-compliant javascript parser written in ECMAScript",
"main": "dist/meriyah.umd.js",
"module": "dist/meriyah.esm.js",
Expand Down
79 changes: 64 additions & 15 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,8 @@ export function parseFunctionBody(
Token.RightBrace
);

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

if (parser.token === Token.Assign) report(parser, Errors.InvalidStatementStart);
return {
type: 'BlockStatement',
Expand Down Expand Up @@ -2565,7 +2567,6 @@ export function parsePrimaryExpressionExtended(
if (context & Context.Strict) report(parser, Errors.StrictEvalArguments);
parser.flags |= Flags.SimpleParameterList;
}

if (!assignable) report(parser, Errors.InvalidAssignmentTarget);

return parseArrowFunctionExpression(parser, context, [expr], /* isAsync */ 0);
Expand Down Expand Up @@ -3831,8 +3832,6 @@ export function parseObjectLiteralOrPattern(
if (tokenValue === '__proto__') prototypeCount++;

if (parser.token & Token.IsIdentifier) {
const t = parser.token;

value = parsePrimaryExpressionExtended(parser, context, type, /* inNewExpression */ 0, /* assignable */ 1);

const { token } = parser;
Expand Down Expand Up @@ -3964,10 +3963,8 @@ export function parseObjectLiteralOrPattern(

value = parseMemberOrUpdateExpression(parser, context, value, /* isNewExpression */ 0);

const assignable = parser.token === Token.Assign;

if (parser.token === Token.Comma || parser.token === Token.RightBrace) {
if (assignable || token === Token.RightBrace || token === Token.Comma) {
if (token === Token.Assign || token === Token.RightBrace || token === Token.Comma) {
if (parser.assignable & AssignmentKind.NotAssignable) destructible |= DestructuringKind.NotDestructible;
} else {
destructible |=
Expand All @@ -3976,6 +3973,12 @@ export function parseObjectLiteralOrPattern(
: DestructuringKind.NotDestructible;
}
} else if (parser.token === Token.Assign) {
destructible |=
parser.assignable & AssignmentKind.NotAssignable
? DestructuringKind.NotDestructible
: token === Token.Assign
? 0
: DestructuringKind.Assignable;
value = parseAssignmentExpression(
parser,
(context | Context.DisallowInContext) ^ Context.DisallowInContext,
Expand All @@ -3995,28 +3998,73 @@ export function parseObjectLiteralOrPattern(
? parseArrayExpressionOrPattern(parser, context, /* skipInitializer */ 0, type)
: parseObjectLiteralOrPattern(parser, context, /* skipInitializer */ 0, type);

destructible |= parser.destructible;
destructible = parser.destructible;

parser.assignable =
parser.destructible & DestructuringKind.NotDestructible
destructible & DestructuringKind.NotDestructible
? AssignmentKind.NotAssignable
: AssignmentKind.Assignable;

if (parser.token === Token.Comma || parser.token === Token.RightBrace) {
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.NotDestructible;
}
if (parser.assignable & AssignmentKind.NotAssignable) destructible |= DestructuringKind.NotDestructible;
} else {
value = parseMemberOrUpdateExpression(parser, context, value, /* assignable */ 0);
if (parser.token !== Token.Assign) destructible |= DestructuringKind.Assignable;

destructible =
parser.assignable & AssignmentKind.NotAssignable ? destructible | DestructuringKind.NotDestructible : 0;

const notAssignable = parser.token !== Token.Assign;

if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) {
if (notAssignable) destructible |= DestructuringKind.NotDestructible;

value = parseAssignmentExpression(
parser,
(context | Context.DisallowInContext) ^ Context.DisallowInContext,
value
);

if (notAssignable) destructible |= DestructuringKind.NotDestructible;
} else if (notAssignable) {
destructible |=
type || parser.assignable & AssignmentKind.NotAssignable
? DestructuringKind.NotDestructible
: DestructuringKind.Assignable;
}
}
} else {
value = parseExpression(parser, context, /* aassignable */ 1);
value = parseLeftHandSideExpression(parser, context, /* assignable */ 1);

destructible |=
(parser.assignable & AssignmentKind.Assignable
parser.assignable & AssignmentKind.Assignable
? DestructuringKind.Assignable
: DestructuringKind.NotDestructible) | parser.assignable;
: DestructuringKind.NotDestructible;

if (parser.token === Token.Comma || parser.token === Token.RightBrace) {
if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.NotDestructible;
}
} else {
value = parseMemberOrUpdateExpression(parser, context, value, /* isNewExpression */ 0);
if (parser.assignable & AssignmentKind.Assignable) {
destructible = 0;
} else {
destructible |= DestructuringKind.NotDestructible;
}

const { token } = parser;

if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) {
value = parseAssignmentExpression(
parser,
(context | Context.DisallowInContext) ^ Context.DisallowInContext,
value
);
if (token !== Token.Assign) {
destructible |= DestructuringKind.NotDestructible;
}
}
}
}
} else if (parser.token === Token.LeftParen) {
state |= PropertyKind.Method;
Expand Down Expand Up @@ -4434,6 +4482,7 @@ export function parseIdentifierOrArrow(
assignable: 0 | 1
): ESTree.Identifier | ESTree.ArrowFunctionExpression {
if (parser.token === Token.Arrow) {
parser.flags = (parser.flags | Flags.SimpleParameterList) ^ Flags.SimpleParameterList;
if (!assignable) report(parser, Errors.InvalidAssignmentTarget);
return parseArrowFunctionExpression(parser, context, [expr], /* isAsync */ 0);
}
Expand Down
2 changes: 1 addition & 1 deletion test/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## Meriyah test suite

Runs ~67 000 tests
Runs ~71 000 tests
64 changes: 64 additions & 0 deletions test/parser/declarations/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,70 @@ describe('Declarations - Function', () => {
sourceType: 'script'
}
],
[
'function a( a = b ) {} n => { "use strict"; }',
Context.None,
{
body: [
{
async: false,
body: {
body: [],
type: 'BlockStatement'
},
expression: false,
generator: false,
id: {
name: 'a',
type: 'Identifier'
},
params: [
{
left: {
name: 'a',
type: 'Identifier'
},
right: {
name: 'b',
type: 'Identifier'
},
type: 'AssignmentPattern'
}
],
type: 'FunctionDeclaration'
},
{
expression: {
async: false,
body: {
body: [
{
expression: {
type: 'Literal',
value: 'use strict'
},
type: 'ExpressionStatement'
}
],
type: 'BlockStatement'
},
expression: false,
id: null,
params: [
{
name: 'n',
type: 'Identifier'
}
],
type: 'ArrowFunctionExpression'
},
type: 'ExpressionStatement'
}
],
sourceType: 'script',
type: 'Program'
}
],
[
'function f() {var f}',
Context.None,
Expand Down
2 changes: 2 additions & 0 deletions test/parser/statements/for-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ describe('Statements - For of', () => {

for (const arg of [
'for({a=0} of b);',
'for ({[a]: ""[b]} of c) {}',
'for ({[a]: ""[b] = c} of d) {}',
'for (let of of ([0])) { }',
'for (let of of [0]) { }',
'for (let of; false; ) { }',
Expand Down

0 comments on commit f48b486

Please sign in to comment.