Skip to content

Commit 0546042

Browse files
committed
Add support for parsing destructuring patterns in arrow function parameter lists
1 parent bbd7142 commit 0546042

File tree

4 files changed

+130
-5
lines changed

4 files changed

+130
-5
lines changed

src/compiler/parser.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3221,10 +3221,27 @@ module ts {
32213221
}
32223222
}
32233223

3224-
// Simple case: "(..."
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();
3231+
}
3232+
3233+
if (possiblyInArrayBindingPattern) {
3234+
// If we are possibly in an array binding pattern, skip empty elements
3235+
while (second === SyntaxKind.CommaToken) {
3236+
second = nextToken();
3237+
}
3238+
}
3239+
3240+
// Simple case: "(..." or "([...", but not "({..."
32253241
// This is an arrow function with a rest parameter.
3226-
if (second === SyntaxKind.DotDotDotToken) {
3227-
return Tristate.True;
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;
32283245
}
32293246

32303247
// If we had "(" followed by something that's not an identifier,
@@ -3236,9 +3253,9 @@ module ts {
32363253
return Tristate.False;
32373254
}
32383255

3239-
// If we have something like "(a:", then we must have a
3256+
// If we have something like "(a:", but not "({ a:", then we must have a
32403257
// type-annotated parameter in an arrow function expression.
3241-
if (nextToken() === SyntaxKind.ColonToken) {
3258+
if (nextToken() === SyntaxKind.ColonToken && !possiblyInObjectBindingPattern) {
32423259
return Tristate.True;
32433260
}
32443261

tests/baselines/reference/arrowFunctionExpressions.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ var d = n => c = n;
1313
var d = (n) => c = n;
1414
var d: (n: any) => any;
1515

16+
// Binding patterns in arrow functions
17+
var p1 = ([a]) => { };
18+
var p2 = ([...a]) => { };
19+
var p3 = ([, a]) => { };
20+
var p4 = ([, ...a]) => { };
21+
var p5 = ([a = 1]) => { };
22+
var p6 = ({ a }) => { };
23+
var p7 = ({ a: { b } }) => { };
24+
var p8 = ({ a = 1 }) => { };
25+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
26+
var p10 = ([{ value, done }]) => { };
1627

1728
// Arrow function used in class member initializer
1829
// Arrow function used in class member function
@@ -100,6 +111,37 @@ var c;
100111
var d = function (n) { return c = n; };
101112
var d = function (n) { return c = n; };
102113
var d;
114+
// Binding patterns in arrow functions
115+
var p1 = function (_a) {
116+
var a = _a[0];
117+
};
118+
var p2 = function (_a) {
119+
var a = _a.slice(0);
120+
};
121+
var p3 = function (_a) {
122+
var a = _a[1];
123+
};
124+
var p4 = function (_a) {
125+
var a = _a.slice(1);
126+
};
127+
var p5 = function (_a) {
128+
var _b = _a[0], a = _b === void 0 ? 1 : _b;
129+
};
130+
var p6 = function (_a) {
131+
var a = _a.a;
132+
};
133+
var p7 = function (_a) {
134+
var b = _a.a.b;
135+
};
136+
var p8 = function (_a) {
137+
var _b = _a.a, a = _b === void 0 ? 1 : _b;
138+
};
139+
var p9 = function (_a) {
140+
var _b = _a.a, _c = (_b === void 0 ? { b: 1 } : _b).b, b = _c === void 0 ? 1 : _c;
141+
};
142+
var p10 = function (_a) {
143+
var _b = _a[0], value = _b.value, done = _b.done;
144+
};
103145
// Arrow function used in class member initializer
104146
// Arrow function used in class member function
105147
var MyClass = (function () {

tests/baselines/reference/arrowFunctionExpressions.types

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,61 @@ var d: (n: any) => any;
5151
>d : (n: any) => any
5252
>n : any
5353

54+
// Binding patterns in arrow functions
55+
var p1 = ([a]) => { };
56+
>p1 : ([a]: [any]) => void
57+
>([a]) => { } : ([a]: [any]) => void
58+
>a : any
59+
60+
var p2 = ([...a]) => { };
61+
>p2 : ([...a]: any[]) => void
62+
>([...a]) => { } : ([...a]: any[]) => void
63+
>a : any[]
64+
65+
var p3 = ([, a]) => { };
66+
>p3 : ([, a]: [any, any]) => void
67+
>([, a]) => { } : ([, a]: [any, any]) => void
68+
>a : any
69+
70+
var p4 = ([, ...a]) => { };
71+
>p4 : ([, ...a]: any[]) => void
72+
>([, ...a]) => { } : ([, ...a]: any[]) => void
73+
>a : any[]
74+
75+
var p5 = ([a = 1]) => { };
76+
>p5 : ([a = 1]: [number]) => void
77+
>([a = 1]) => { } : ([a = 1]: [number]) => void
78+
>a : number
79+
80+
var p6 = ({ a }) => { };
81+
>p6 : ({ a }: { a: any; }) => void
82+
>({ a }) => { } : ({ a }: { a: any; }) => void
83+
>a : any
84+
85+
var p7 = ({ a: { b } }) => { };
86+
>p7 : ({ a: { b } }: { a: { b: any; }; }) => void
87+
>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void
88+
>a : unknown
89+
>b : any
90+
91+
var p8 = ({ a = 1 }) => { };
92+
>p8 : ({ a = 1 }: { a?: number; }) => void
93+
>({ a = 1 }) => { } : ({ a = 1 }: { a?: number; }) => void
94+
>a : number
95+
96+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
97+
>p9 : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void
98+
>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void
99+
>a : unknown
100+
>b : number
101+
>{ b: 1 } : { b: number; }
102+
>b : number
103+
104+
var p10 = ([{ value, done }]) => { };
105+
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
106+
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
107+
>value : any
108+
>done : any
54109

55110
// Arrow function used in class member initializer
56111
// Arrow function used in class member function

tests/cases/conformance/expressions/functions/arrowFunctionExpressions.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ var d = n => c = n;
1212
var d = (n) => c = n;
1313
var d: (n: any) => any;
1414

15+
// Binding patterns in arrow functions
16+
var p1 = ([a]) => { };
17+
var p2 = ([...a]) => { };
18+
var p3 = ([, a]) => { };
19+
var p4 = ([, ...a]) => { };
20+
var p5 = ([a = 1]) => { };
21+
var p6 = ({ a }) => { };
22+
var p7 = ({ a: { b } }) => { };
23+
var p8 = ({ a = 1 }) => { };
24+
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
25+
var p10 = ([{ value, done }]) => { };
1526

1627
// Arrow function used in class member initializer
1728
// Arrow function used in class member function

0 commit comments

Comments
 (0)