Skip to content

Commit

Permalink
fix(parser): fixed a few non-throwing edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed May 10, 2019
1 parent 9ecdd55 commit 8977bd8
Show file tree
Hide file tree
Showing 12 changed files with 589 additions and 71 deletions.
1 change: 0 additions & 1 deletion src/lexer/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ export function scanSingleToken(parser: ParserState, context: Context): Token {
break;
// Line terminators
case Token.LineTerminator:
isStartOfLine = true;
parser.flags |= Flags.NewLine;
if (
CharTypes[first] & CharFlags.CarriageReturn &&
Expand Down
4 changes: 2 additions & 2 deletions src/lexer/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function scanTemplate(parser: ParserState, context: Context): Token {
} else {
if (ch === Chars.CarriageReturn) {
if (parser.index < parser.length && parser.source.charCodeAt(parser.index) === Chars.LineFeed) {
if (ret !== null) ret += fromCodePoint(ch);
ret += fromCodePoint(ch);
parser.currentCodePoint = parser.source.charCodeAt(++parser.index);
}
}
Expand All @@ -51,7 +51,7 @@ export function scanTemplate(parser: ParserState, context: Context): Token {
parser.column = -1;
parser.line++;
}
if (ret !== null) ret += fromCodePoint(ch);
ret += fromCodePoint(ch);
}
if (parser.index >= parser.length) report(parser, Errors.UnterminatedTemplate);
ch = nextCodePoint(parser);
Expand Down
129 changes: 72 additions & 57 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2239,36 +2239,34 @@ export function parseFunctionBody(
const body: ESTree.Statement[] = [];

if (parser.token !== Token.RightBrace) {
// Avoid this if the 'OptionsDirectives' is off, to speed things up.
if ((context & Context.OptionsDirectives) === 0) {
// The grammar is documented here:
// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
while (parser.token === Token.StringLiteral) {
// "use strict" must be the exact literal without escape sequences or line continuation.
if (parser.index - parser.startIndex < 13 && parser.tokenValue === 'use strict') {
context |= Context.Strict;
// TC39 deemed "use strict" directives to be an error when occurring
// in the body of a function with non-simple parameter list, on
// 29/7/2015. https://goo.gl/ueA7Ln
if (parser.flags & Flags.SimpleParameterList) {
reportAt(parser, parser.index, parser.line, parser.startIndex, Errors.IllegalUseStrict);
}
// The grammar is documented here:
// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
while (parser.token === Token.StringLiteral) {
// "use strict" must be the exact literal without escape sequences or line continuation.
if (parser.index - parser.startIndex < 13 && parser.tokenValue === 'use strict') {
context |= Context.Strict;
// TC39 deemed "use strict" directives to be an error when occurring
// in the body of a function with non-simple parameter list, on
// 29/7/2015. https://goo.gl/ueA7Ln
if (parser.flags & Flags.SimpleParameterList) {
reportAt(parser, parser.index, parser.line, parser.startIndex, Errors.IllegalUseStrict);
}
body.push(parseDirective(parser, context));
}
if (
context & Context.Strict &&
firstRestricted &&
(firstRestricted & Token.IsEvalOrArguments) === Token.IsEvalOrArguments
) {
report(parser, Errors.StrictFunctionName);
}
body.push(parseDirective(parser, context));
}

while (parser.token !== Token.RightBrace) {
body.push(parseStatementListItem(parser, context) as ESTree.Statement);
if (
context & Context.Strict &&
firstRestricted &&
(firstRestricted & Token.IsEvalOrArguments) === Token.IsEvalOrArguments
) {
report(parser, Errors.StrictFunctionName);
}
}

while (parser.token !== Token.RightBrace) {
body.push(parseStatementListItem(parser, context) as ESTree.Statement);
}

consume(
parser,
origin & (BindingOrigin.Arrow | BindingOrigin.Declaration) ? context | Context.AllowRegExp : context,
Expand Down Expand Up @@ -3046,7 +3044,7 @@ export function parseArrayExpressionOrPattern(
parser: ParserState,
context: Context,
skipInitializer: 0 | 1,
bindingType: BindingType
type: BindingType
): ESTree.ArrayExpression | ESTree.ArrayPattern {
/* ArrayLiteral :
* [ Elisionopt ]
Expand Down Expand Up @@ -3102,13 +3100,7 @@ export function parseArrayExpressionOrPattern(
let left: any;

if (parser.token & Token.IsIdentifier) {
left = parsePrimaryExpressionExtended(
parser,
context,
bindingType,
/* inNewExpression */ 0,
/* assignable */ 1
);
left = parsePrimaryExpressionExtended(parser, context, type, /* inNewExpression */ 0, /* assignable */ 1);
if (consumeOpt(parser, context | Context.AllowRegExp, Token.Assign)) {
if (parser.assignable & AssignmentKind.NotAssignable) {
reportAt(parser, parser.index, parser.line, parser.index - 3, Errors.InvalidLHS);
Expand All @@ -3122,7 +3114,7 @@ export function parseArrayExpressionOrPattern(
} else if (parser.token === Token.Comma || parser.token === Token.RightBracket) {
destructible |= parser.assignable & AssignmentKind.NotAssignable ? DestructuringKind.NotDestructible : 0;
} else {
if (bindingType) destructible |= DestructuringKind.NotDestructible;
if (type) destructible |= DestructuringKind.NotDestructible;

left = parseMemberOrUpdateExpression(parser, context, left, /* assignable */ 0);

Expand All @@ -3133,16 +3125,16 @@ export function parseArrayExpressionOrPattern(
left = parseAssignmentExpression(parser, context, left);
} else if (parser.token !== Token.Assign) {
destructible |=
bindingType || parser.assignable & AssignmentKind.NotAssignable
type || parser.assignable & AssignmentKind.NotAssignable
? DestructuringKind.NotDestructible
: DestructuringKind.Assignable;
}
}
} else if (parser.token & Token.IsPatternStart) {
left =
parser.token === Token.LeftBrace
? parseObjectLiteralOrPattern(parser, context, skipInitializer, bindingType)
: parseArrayExpressionOrPattern(parser, context, skipInitializer, bindingType);
? parseObjectLiteralOrPattern(parser, context, skipInitializer, type)
: parseArrayExpressionOrPattern(parser, context, skipInitializer, type);

destructible |= parser.destructible;

Expand All @@ -3165,13 +3157,13 @@ export function parseArrayExpressionOrPattern(
left = parseAssignmentExpression(parser, context, left);
} else if (parser.token !== Token.Assign) {
destructible |=
bindingType || parser.assignable & AssignmentKind.NotAssignable
type || parser.assignable & AssignmentKind.NotAssignable
? DestructuringKind.NotDestructible
: DestructuringKind.Assignable;
}
}
} else if (parser.token === Token.Ellipsis) {
left = parseRestOrSpreadElement(parser, context, Token.RightBracket, bindingType, /* isAsync */ 0);
left = parseRestOrSpreadElement(parser, context, Token.RightBracket, type, /* isAsync */ 0);
destructible |= parser.destructible;
if (parser.token !== Token.Comma && parser.token !== Token.RightBracket)
report(parser, Errors.UnexpectedToken, KeywordDescTable[parser.token & Token.Type]);
Expand All @@ -3182,12 +3174,16 @@ export function parseArrayExpressionOrPattern(

if (parser.token !== Token.Comma && parser.token !== Token.RightBracket) {
left = parseAssignmentExpression(parser, context, left);
parser.assignable = AssignmentKind.NotAssignable;
parser.destructible = DestructuringKind.NotDestructible;
} else if (token === Token.LeftParen && parser.assignable & AssignmentKind.Assignable && !bindingType) {
destructible |= DestructuringKind.Assignable;
} else if (token === Token.LeftParen || parser.assignable & AssignmentKind.NotAssignable) {
if (type && token === Token.LeftParen) destructible |= DestructuringKind.NotDestructible;
} else if (parser.assignable & AssignmentKind.NotAssignable) {
destructible |= DestructuringKind.NotDestructible;
} else if (token === Token.LeftParen) {
destructible |=
parser.assignable & AssignmentKind.Assignable && !type
? DestructuringKind.Assignable
: token === Token.LeftParen || parser.assignable & AssignmentKind.NotAssignable
? DestructuringKind.NotDestructible
: 0;
}
}

Expand Down Expand Up @@ -3628,10 +3624,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 @@ -3640,6 +3634,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 Down Expand Up @@ -3781,24 +3781,38 @@ export function parseObjectLiteralOrPattern(
if (parser.token & Token.IsIdentifier) {
value = parsePrimaryExpressionExtended(parser, context, type, /* inNewExpression */ 0, /* assignable */ 1);

const isRightBraceOrComma = parser.token === Token.RightBrace || parser.token === Token.Comma;
const { token } = parser;

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

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

if (parser.token !== Token.Comma && parser.token !== Token.RightBrace) {
if (parser.token === Token.Comma || parser.token === Token.RightBrace) {
if (token === Token.Assign || token === Token.RightBrace || token === Token.Comma) {
if (parser.assignable & AssignmentKind.NotAssignable) destructible |= DestructuringKind.NotDestructible;
} else {
destructible |=
parser.assignable & AssignmentKind.Assignable
? DestructuringKind.Assignable
: 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,
value
);

if (!assignable) destructible |= DestructuringKind.NotDestructible;
} else if (parser.assignable & AssignmentKind.NotAssignable) {
} else {
destructible |= DestructuringKind.NotDestructible;
} else if (!isRightBraceOrComma) {
destructible |= DestructuringKind.Assignable;
value = parseAssignmentExpression(
parser,
(context | Context.DisallowInContext) ^ Context.DisallowInContext,
value
);
}
} else if ((parser.token & Token.IsPatternStart) === Token.IsPatternStart) {
value =
Expand Down Expand Up @@ -4298,7 +4312,8 @@ export function parseParenthesizedExpression(parser: ParserState, context: Conte
return parseArrowFunctionExpression(parser, context, toplevelComma ? expressions : [expr], /* isAsync */ 0);
} else if (destructible & DestructuringKind.Required) {
report(parser, Errors.InvalidShorthandPropInit);
} else if (context & Context.OptionsWebCompat && parser.destructible & DestructuringKind.SeenProto) {
}
if (context & Context.OptionsWebCompat && parser.destructible & DestructuringKind.SeenProto) {
report(parser, Errors.DuplicateProto);
}

Expand Down
4 changes: 2 additions & 2 deletions test/parser/declarations/let.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,12 @@ describe('Declarations - Let', () => {
['let [({x: 1})] = [];', Context.None],
['let [(x)] = [];', Context.None],
['let [({x: 1}) = y] = [];', Context.None],
// ['let [(x) = y] = [];', Context.None],
['let [(x) = y] = [];', Context.None],
['var [({x: 1})] = [];', Context.None],
['var [(x)] = [];', Context.None],
['var [({x: 1}) = y] = [];', Context.None],
['if (true) let x = 1;', Context.None],
// ['let {x:o.f=1}={x:1}', Context.None],
['let {x:o.f=1}={x:1}', Context.None],
['let [o.x=1]=[]', Context.None],
['(o.f=1)=>0', Context.None],
['let x = ...y;', Context.None],
Expand Down
Loading

0 comments on commit 8977bd8

Please sign in to comment.