Skip to content

Commit

Permalink
fix(parser): fixed a slip up
Browse files Browse the repository at this point in the history
Latest changes behave like "AssignmentExpression", but avoid double validation and extra branching if found a assignment operator. If no assign operator,  goes on as normal.
  • Loading branch information
KFlash committed Aug 10, 2019
1 parent 6f04c41 commit e9f5950
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 19 additions & 7 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5340,7 +5340,8 @@ function parseSpreadOrRestElement(
} else {
if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
argument = parseBinaryExpression(parser, context, 1, tokenPos, linePos, colPos, 4, token, argument as any);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
argument = parseConditionalExpression(parser, context, argument as any, tokenPos, linePos, colPos);
}
destructible |=
Expand Down Expand Up @@ -5757,7 +5758,8 @@ export function parseObjectLiteralOrPattern(
destructible |= DestructuringKind.CannotDestruct;
if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
value = parseBinaryExpression(parser, context, 1, tokenPos, linePos, colPos, 4, token, value);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
value = parseConditionalExpression(parser, context, value, tokenPos, linePos, colPos);
}
}
Expand Down Expand Up @@ -5819,7 +5821,8 @@ export function parseObjectLiteralOrPattern(
} else {
if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
value = parseBinaryExpression(parser, context, 1, tokenPos, linePos, colPos, 4, token, value);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
value = parseConditionalExpression(parser, context, value, tokenPos, linePos, colPos);
}
destructible |=
Expand Down Expand Up @@ -5920,12 +5923,17 @@ export function parseObjectLiteralOrPattern(
} else if (parser.token === Token.Multiply) {
destructible |= DestructuringKind.CannotDestruct;

if (token === Token.GetKeyword || token === Token.SetKeyword || token === Token.AnyIdentifier) {
if (token === Token.GetKeyword || token === Token.SetKeyword) {
report(parser, Errors.InvalidGeneratorGetter);
} else if (token === Token.AnyIdentifier) {
report(parser, Errors.InvalidEscapedKeyword);
}

nextToken(parser, context);

state |=
PropertyKind.Generator | PropertyKind.Method | (token === Token.AsyncKeyword ? PropertyKind.Async : 0);

if (parser.token & Token.IsIdentifier) {
key = parseIdentifier(parser, context, 0);
} else if ((parser.token & Token.IsStringOrNumber) === Token.IsStringOrNumber) {
Expand Down Expand Up @@ -5984,6 +5992,7 @@ export function parseObjectLiteralOrPattern(

if (parser.token & Token.IsIdentifier) {
value = parsePrimaryExpressionExtended(parser, context, kind, 0, 1, 0, inGroup, tokenPos, linePos, colPos);

const { token, tokenValue: valueAfterColon } = parser;

value = parseMemberOrUpdateExpression(parser, context, value, inGroup, 0, 0, tokenPos, linePos, colPos);
Expand Down Expand Up @@ -6065,7 +6074,8 @@ export function parseObjectLiteralOrPattern(
} else {
if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
value = parseBinaryExpression(parser, context, 1, tokenPos, linePos, colPos, 4, token, value);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
value = parseConditionalExpression(parser, context, value, tokenPos, linePos, colPos);
}
destructible |=
Expand Down Expand Up @@ -6225,7 +6235,8 @@ export function parseObjectLiteralOrPattern(
} else {
if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
value = parseBinaryExpression(parser, context, 1, tokenPos, linePos, colPos, 4, token, value);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
value = parseConditionalExpression(parser, context, value, tokenPos, linePos, colPos);
}
destructible |=
Expand Down Expand Up @@ -7563,7 +7574,8 @@ export function parseAsyncArrowOrCallExpression(

if ((parser.token & Token.IsBinaryOp) === Token.IsBinaryOp) {
expr = parseBinaryExpression(parser, context, 1, start, line, column, 4, token, expr as ESTree.Expression);
} else if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
}
if (consumeOpt(parser, context | Context.AllowRegExp, Token.QuestionMark)) {
expr = parseConditionalExpression(parser, context, expr as ESTree.Expression, start, line, column);
}
}
Expand Down
9 changes: 9 additions & 0 deletions test/parser/declarations/async-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ describe('Declarations - Async Function', () => {
'async function fn() { const x = await import({}); }',
'async function fn() { const x = await import({}); }',
'async function * fn() { return import(yield 42); }',
'async function f() { let\narguments }',
'async function f() { let\ninterface }',
'async function f() { let\npackage }',
'async function f() { for await (x[a in b] of y); }',
'async function a() { await a.b[c](d).e; }',
'await.b[c](d).e;',
Expand Down Expand Up @@ -410,6 +413,8 @@ describe('Declarations - Async Function', () => {
['async (a = await) => {}', Context.None],
['async (...await) => 1', Context.None],
['async ([await]) => 1', Context.None],
['async function f() { let\nyield 0 }', Context.None],
['async function f() { "use strict"; let\nawait 0 }', Context.None],
['async ([...await]) => 1', Context.None],
['async (b = {await}) => 1', Context.None],
['async (b = {a: await}) => 1', Context.None],
Expand Down Expand Up @@ -452,6 +457,10 @@ describe('Declarations - Async Function', () => {
['async function foo (foo) { super.prop };', Context.None],
['async function foo (foo) { super.prop };', Context.None],
['"use strict"; async function eval () { }', Context.None],
['async function f() { let\narguments.length }', Context.None],
['async function f() { let\narguments.await }', Context.None],
['async function f() { let\narguments.package }', Context.None],
['async function f() { let\narguments.yield }', Context.None],
['async function foo (foo = super()) { let bar; }', Context.None],
['async function a(){ (foo = +await bar) => {} }', Context.None],
['async function a(){ (foo = [{m: 5 + t(+await bar)}]) => {} }', Context.None],
Expand Down
18 changes: 18 additions & 0 deletions test/parser/declarations/let.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ describe('Declarations - Let', () => {
'let [foo] = arr;',
'let [,] = x;',
'let [,,] = x;',
'letarguments',
'letarguments.length',
'let\nawait',
'let\nimplements',
'let\ninterface',
'letpackage',
'letprivate',
'letyield',
'let eval',
'let eval',
'let implements',
'let eval',
'let\nfoo',
'let\n[foo]\r=\n2\n;',
'let foo = bar, zoo = boo',
Expand Down Expand Up @@ -382,13 +394,16 @@ describe('Declarations - Let', () => {
['for(let let in { }) { };', Context.None],
['let [a];', Context.None],
['let let;', Context.None],
['let let x;', Context.None],
['if (1) let x = 10;', Context.None],
['let [a + 1] = [];', Context.None],
['let a; [a--] = [];', Context.None],
['let a; [1, a] = [];', Context.None],
['let [...a, b] = [];', Context.None],
['let a; [...a = 1] = [];', Context.None],
['let a; [((a)] = [];', Context.None],
['let\neval(foo)', Context.None],
['let eval(foo)', Context.None],
['let [((a)] = [];', Context.None],
['function foo() { return {}; }; let [foo().x] = [];', Context.None],
['function foo() { return {}; }; [foo()] = [];', Context.None],
Expand All @@ -405,6 +420,7 @@ describe('Declarations - Let', () => {
['for (let [let];;;) {}', Context.None],
['for (let x, y, z, let = 1;;;) {}', Context.None],
['let x,;', Context.None],
['let await 0', Context.None],
['"use strict"; const let = 1;', Context.None],
['"use strict"; let { let } = {};', Context.None],
['"use strict"; const { let } = {};', Context.None],
Expand All @@ -427,6 +443,7 @@ describe('Declarations - Let', () => {
['let [...a = 1] = [];', Context.None],
['let a; [...a = 1] = [];', Context.None],
['let a; [...a,] = [];', Context.None],
['let arguments.length', Context.None],
['let [...a, ...b] = [];', Context.None],
['let [1, a] = [];', Context.None],
['let [1] = [];', Context.None],
Expand Down Expand Up @@ -493,6 +510,7 @@ describe('Declarations - Let', () => {
['let [...x, y] = [1, 2, 3];', Context.None],
['let [...{ x }, y] = [1, 2, 3];', Context.None],
['let [...x = []] = [];', Context.None],
['let\nyield 0', Context.None],
// 'let' should not be an allowed name in destructuring let declarations
['let [a, let, b] = [1, 2, 3];', Context.None],
// Babylon issue: https://github.com/babel/babylon/issues/148
Expand Down
5 changes: 4 additions & 1 deletion test/parser/expressions/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ describe('Expressions - Object', () => {
'{[d]: {}[d] += a}',
'{"d": {}[d] += a}',
'{"d": {}[x ? y : z] += a}',
'{d: {}[x ? y : z] += a}'
'{d: {}[x ? y : z] += a}',
'{ b: c.d === e ? f : g }',
'{ "b": c.d === e ? f : g }',
'{ [b]: c.d === e ? f : g }'
]) {
it(`'use strict'; x = ${arg}`, () => {
t.doesNotThrow(() => {
Expand Down
6 changes: 4 additions & 2 deletions test/parser/lexical/try.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fail } from '../../test-utils';
import * as t from 'assert';
import { parseSource } from '../../../src/parser';

describe('Miscellaneous - Try', () => {
describe('Lexical - Try', () => {
for (const declaration of ['var e', 'var f, e', 'let {} = 0', 'let {e:f} = 0', '{ function e(){} }']) {
it(`try { throw 0; } catch(e) { ${declaration} }`, () => {
t.doesNotThrow(() => {
Expand Down Expand Up @@ -68,8 +68,9 @@ describe('Miscellaneous - Try', () => {
});
}

fail('Statements - Try (fail)', [
fail('Lexical - Try (fail)', [
['try {} catch (arguments) { }', Context.OptionsLexical | Context.Strict],
['try { throw "try"; } catch (x) { for (var x = y; x !== y; x++) {}}', Context.OptionsLexical | Context.Strict],
['try {} catch (arguments) { }', Context.Strict],
['try {} catch (e) { for (var e in y) {} }', Context.OptionsLexical],
['try {} catch (e) { for (var e;;) {} }', Context.OptionsLexical],
Expand Down Expand Up @@ -261,6 +262,7 @@ describe('Miscellaneous - Try', () => {
'try { } catch (e) { function f(){} function f(){} }',
'try {} catch (foo) { var foo; }',
'try {} catch (e) { for (var e of y) {} }',
'try { throw "try"; } catch (x) { for (var x = y; x !== y; x++) {}}',
'try { } catch (e) { function *f(){} function *f(){} }'
]) {
it(`${arg}`, () => {
Expand Down
1 change: 1 addition & 0 deletions test/parser/miscellaneous/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe('Miscellaneous - JSX', () => {
'<Component {...x}></Component>;',
'<Component.Test />;',
'<div>{...this.props.children}</div>;',
'{foo && <Something foo={foo} /> }',
'<Component:Test />;',
'<Component.Test />;',
`<></>;
Expand Down
50 changes: 50 additions & 0 deletions test/parser/miscellaneous/regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Context } from '../../../src/common';
import { pass, fail } from '../../test-utils';
import * as t from 'assert';
import { parseSource } from '../../../src/parser';

describe('Miscellaneous - Regular expressions', () => {
for (const arg of [
// '/(?<abc𝟐def>foo\\k<abc𝟐def>)/',
// '/(?<輸xyz>foo)met\\k<輸xyz>/',
'x = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;'
]) {
it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.OptionsNext | Context.OptionsLexical);
});
});
it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.OptionsNext | Context.OptionsWebCompat | Context.OptionsLexical);
});
});
}

fail('Miscellaneous - Regular expressions (fail)', [
['function *f(){ s = {foo: yield / x} }', Context.OptionsNext],
['s = {foo: yield / x}', Context.OptionsNext | Context.Strict],
['function *f(){ s = {"foo": yield / x} }', Context.OptionsNext],
['/(?<a>.)\\k<a/', Context.OptionsNext],
['/\\k<a(?<a>a)/', Context.OptionsNext],
['/(?<42a>a)/', Context.OptionsNext],
['/(?<𝟐rest>foo)/', Context.OptionsNext],
['/(?<𝟐>foo)/', Context.OptionsNext],
['/(?<\\uD835\\uDFD0rest>foo)/', Context.OptionsWebCompat],
['/(?<abc\\uD835\\uDFD0def>foo\\k<abc\\uD835def>)/', Context.OptionsNext | Context.Module | Context.Strict],
['/(?<\\ud87e\\udddfrest>foo)/', Context.OptionsNext | Context.OptionsWebCompat],
[
`function* f(){ yield
/foo }`,
Context.OptionsNext | Context.Module | Context.Strict
],
['function l(){((/)/))(/]/)};', Context.OptionsNext | Context.Module | Context.Strict],
['0 ?? 1 && 2', Context.OptionsNext | Context.Module | Context.Strict],
[
'3 ?? 2 ** 1 % 0 / 9 * 8 - 7 + 6 >>> 5 >> 4 << 3 >= 2 <= 1 > 0 < 9 !== 8 === 7 != 6 == 5 & 4 ^ 3 | 2 && 1 || 0',
Context.OptionsNext
],
['e ?? f ?? g || h;', Context.OptionsNext | Context.Module | Context.Strict],
['c && d ?? e', Context.OptionsNext | Context.Module | Context.Strict]
]);
});
9 changes: 0 additions & 9 deletions test/parser/miscellaneous/trailing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ describe('Miscellaneous - Trailing comma', () => {
'(function a(b, c, ...d,) {});',
'(function* a(b, c, ...d,) {});',
'(function (b, c, ...d,) {});',
'(function* (b, c, ...d,) {});',
'(...b,) => {};',
'(b, c, ...d,) => {};',
'(,);',
Expand All @@ -49,20 +48,12 @@ describe('Miscellaneous - Trailing comma', () => {
', => 0',
', () => 0',
'async (,) => 0',
' function a(b, c, ...d,) {}',
' function* a(b, c, ...d,) {}',
'(function a(b, c, ...d,) {});',
'(function* a(b, c, ...d,) {});',
'(function (b, c, ...d,) {});',
'(function* (b, c, ...d,) {});',
'class A {foo(,) {}}',
'class A {static foo(,) {}}',
'(class {static foo(,) {}})',
'(...b,) => {};',
'(b, c, ...d,) => {};',
'(,);',
'(a,);',
'(a,b,c,);',
'n, op, val,',
'foo(a,,) => 0',
'async (a,,) => 0',
Expand Down
43 changes: 43 additions & 0 deletions test/parser/miscellaneous/unicode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Context } from '../../../src/common';
import * as t from 'assert';
import { parseSource } from '../../../src/parser';

describe('Miscellaneous - Unicode', () => {
for (const arg of [
'var foob\\u123r = 0;',
'var \\u123roo = 0;',
'/regex/\\u0069g',
'var foob\\u{c481r = 0;',
'var foob\\uc481}r = 0;',
'var \\u{0052oo = 0;',
'var \\u0052}oo = 0;',
'var foob\\u{}ar = 0;',
'\\u{110000',
'var foob\\v1234r = 0;',
'var foob\\U1234r = 0;',
'var foob\\v{1234}r = 0;',
'var foob\\U{1234}r = 0;'
]) {
it(`${arg}`, () => {
t.throws(() => {
parseSource(`${arg}`, undefined, Context.OptionsWebCompat);
});
});
}

for (const arg of [
'var \\u0052oo = 0;',
'var \\u{00000000052}oo = 0;',
'var \\u{0052}oo = 0;',
'var \\u{52}oo = 0;',
'var foob\\uc481r = 0;',
'var foob\\u{c481}r = 0;',
'foob\\uc481r'
]) {
it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.OptionsWebCompat);
});
});
}
});
5 changes: 4 additions & 1 deletion test/parser/statements/for-await-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ describe('Statements - For await of', () => {
{ start: 'var a1 = async () => { { ', finish: ' } }' },
{ start: 'var a1 = async () => { if (true) { ', finish: ' } }' },
{ start: 'var a1 = async () => { if (true) ', finish: ' }' },
{ start: 'var a1 = async () => { if (true) foo(); else { ', finish: ' } }' },
{
start: 'var a1 = async () => { if (true) foo(); else { ',
finish: ' } }'
},
{ start: 'var a1 = async () => { while (true) { ', finish: ' } }' },
{ start: 'var a1 = async () => { for(;;) { ', finish: ' } }' },
{ start: "var a1 = async () => { switch(e) { case '1' : ", finish: ' } }' }
Expand Down

0 comments on commit e9f5950

Please sign in to comment.