Skip to content

Commit 19695f9

Browse files
committed
Simplified lookahead and added ES6 test cases
1 parent 0546042 commit 19695f9

File tree

4 files changed

+123
-18
lines changed

4 files changed

+123
-18
lines changed

src/compiler/parser.ts

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3221,30 +3221,44 @@ module ts {
32213221
}
32223222
}
32233223

3224-
// If we had "(" followed by "{" or "[", this could be the start of a binding pattern.
3225-
let possiblyInArrayBindingPattern = false;
3226-
let possiblyInObjectBindingPattern = false;
3227-
while (second === SyntaxKind.OpenBraceToken || second === SyntaxKind.OpenBracketToken) {
3228-
possiblyInObjectBindingPattern = second === SyntaxKind.OpenBraceToken;
3229-
possiblyInArrayBindingPattern = second === SyntaxKind.OpenBracketToken;
3230-
second = nextToken();
3224+
// If encounter "([", this could be the start of an array binding pattern.
3225+
// Examples:
3226+
// ([ x ]) => { }
3227+
// ([ x ])
3228+
if (second === SyntaxKind.OpenBracketToken) {
3229+
// If the next token is not ",", "...", "[", "{", or an identifier, then this could either be
3230+
// an arrow function with an array binding pattern or a parenthesized array literal expression.
3231+
// Otherwise, it cannot be an array binding pattern.
3232+
let third = nextToken();
3233+
if (isIdentifierOrPattern() || third === SyntaxKind.CommaToken || third === SyntaxKind.DotDotDotToken) {
3234+
return Tristate.Unknown;
3235+
}
3236+
3237+
return Tristate.False;
32313238
}
32323239

3233-
if (possiblyInArrayBindingPattern) {
3234-
// If we are possibly in an array binding pattern, skip empty elements
3235-
while (second === SyntaxKind.CommaToken) {
3236-
second = nextToken();
3240+
// If we encounter "({", this could be the start of an object binding pattern.
3241+
// Examples:
3242+
// ({ x }) => { }
3243+
// ({ x })
3244+
// ({ *x() { })
3245+
if (second === SyntaxKind.OpenBraceToken) {
3246+
// If we encountered an asterisk, then this is a generator method on an
3247+
// object literal and cannot be a binding pattern.
3248+
if (nextToken() === SyntaxKind.AsteriskToken) {
3249+
return Tristate.False;
32373250
}
3251+
3252+
return Tristate.Unknown;
32383253
}
32393254

3240-
// Simple case: "(..." or "([...", but not "({..."
3255+
// Simple case: "(..."
32413256
// This is an arrow function with a rest parameter.
3242-
if (second === SyntaxKind.DotDotDotToken && !possiblyInObjectBindingPattern) {
3243-
// if we are possibly in an array binding pattern, then this may be a lambda, otherwise it must be a lambda.
3244-
return possiblyInArrayBindingPattern ? Tristate.Unknown : Tristate.True;
3257+
if (second === SyntaxKind.DotDotDotToken) {
3258+
return Tristate.True;
32453259
}
32463260

3247-
// If we had "(" followed by something that's not an identifier,
3261+
// If we had something like "(" followed by something that's not an identifier,
32483262
// then this definitely doesn't look like a lambda.
32493263
// Note: we could be a little more lenient and allow
32503264
// "(public" or "(private". These would not ever actually be allowed,
@@ -3253,9 +3267,9 @@ module ts {
32533267
return Tristate.False;
32543268
}
32553269

3256-
// If we have something like "(a:", but not "({ a:", then we must have a
3270+
// If we have something like "(a:", then we may have a
32573271
// type-annotated parameter in an arrow function expression.
3258-
if (nextToken() === SyntaxKind.ColonToken && !possiblyInObjectBindingPattern) {
3272+
if (nextToken() === SyntaxKind.ColonToken) {
32593273
return Tristate.True;
32603274
}
32613275

tests/baselines/reference/emitArrowFunctionES6.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ var f4 = (x: string, y: number, z=10) => { }
66
function foo(func: () => boolean) { }
77
foo(() => true);
88
foo(() => { return false; });
9+
10+
// Binding patterns in arrow functions
11+
var p1 = ([a]) => { };
12+
var p2 = ([...a]) => { };
13+
var p3 = ([, a]) => { };
14+
var p4 = ([, ...a]) => { };
15+
var p5 = ([a = 1]) => { };
16+
var p6 = ({ a }) => { };
17+
var p7 = ({ a: { b } }) => { };
18+
var p8 = ({ a = 1 }) => { };
19+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
20+
var p10 = ([{ value, done }]) => { };
921

1022

1123
//// [emitArrowFunctionES6.js]
@@ -16,3 +28,14 @@ var f4 = (x, y, z = 10) => { };
1628
function foo(func) { }
1729
foo(() => true);
1830
foo(() => { return false; });
31+
// Binding patterns in arrow functions
32+
var p1 = ([a]) => { };
33+
var p2 = ([...a]) => { };
34+
var p3 = ([, a]) => { };
35+
var p4 = ([, ...a]) => { };
36+
var p5 = ([a = 1]) => { };
37+
var p6 = ({ a }) => { };
38+
var p7 = ({ a: { b } }) => { };
39+
var p8 = ({ a = 1 }) => { };
40+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
41+
var p10 = ([{ value, done }]) => { };

tests/baselines/reference/emitArrowFunctionES6.types

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,59 @@ foo(() => { return false; });
3737
>foo : (func: () => boolean) => void
3838
>() => { return false; } : () => boolean
3939

40+
// Binding patterns in arrow functions
41+
var p1 = ([a]) => { };
42+
>p1 : ([a]: [any]) => void
43+
>([a]) => { } : ([a]: [any]) => void
44+
>a : any
45+
46+
var p2 = ([...a]) => { };
47+
>p2 : ([...a]: any[]) => void
48+
>([...a]) => { } : ([...a]: any[]) => void
49+
>a : any[]
50+
51+
var p3 = ([, a]) => { };
52+
>p3 : ([, a]: [any, any]) => void
53+
>([, a]) => { } : ([, a]: [any, any]) => void
54+
>a : any
55+
56+
var p4 = ([, ...a]) => { };
57+
>p4 : ([, ...a]: any[]) => void
58+
>([, ...a]) => { } : ([, ...a]: any[]) => void
59+
>a : any[]
60+
61+
var p5 = ([a = 1]) => { };
62+
>p5 : ([a = 1]: [number]) => void
63+
>([a = 1]) => { } : ([a = 1]: [number]) => void
64+
>a : number
65+
66+
var p6 = ({ a }) => { };
67+
>p6 : ({ a }: { a: any; }) => void
68+
>({ a }) => { } : ({ a }: { a: any; }) => void
69+
>a : any
70+
71+
var p7 = ({ a: { b } }) => { };
72+
>p7 : ({ a: { b } }: { a: { b: any; }; }) => void
73+
>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void
74+
>a : unknown
75+
>b : any
76+
77+
var p8 = ({ a = 1 }) => { };
78+
>p8 : ({ a = 1 }: { a?: number; }) => void
79+
>({ a = 1 }) => { } : ({ a = 1 }: { a?: number; }) => void
80+
>a : number
81+
82+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
83+
>p9 : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void
84+
>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void
85+
>a : unknown
86+
>b : number
87+
>{ b: 1 } : { b: number; }
88+
>b : number
89+
90+
var p10 = ([{ value, done }]) => { };
91+
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
92+
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
93+
>value : any
94+
>done : any
95+

tests/cases/conformance/es6/arrowFunction/emitArrowFunctionES6.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,15 @@ var f4 = (x: string, y: number, z=10) => { }
66
function foo(func: () => boolean) { }
77
foo(() => true);
88
foo(() => { return false; });
9+
10+
// Binding patterns in arrow functions
11+
var p1 = ([a]) => { };
12+
var p2 = ([...a]) => { };
13+
var p3 = ([, a]) => { };
14+
var p4 = ([, ...a]) => { };
15+
var p5 = ([a = 1]) => { };
16+
var p6 = ({ a }) => { };
17+
var p7 = ({ a: { b } }) => { };
18+
var p8 = ({ a = 1 }) => { };
19+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
20+
var p10 = ([{ value, done }]) => { };

0 commit comments

Comments
 (0)