diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d6cf4c1a141..5123c2124ac 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3221,6 +3221,16 @@ module ts { } } + // If encounter "([" or "({", this could be the start of a binding pattern. + // Examples: + // ([ x ]) => { } + // ({ x }) => { } + // ([ x ]) + // ({ x }) + if (second === SyntaxKind.OpenBracketToken || second === SyntaxKind.OpenBraceToken) { + return Tristate.Unknown; + } + // Simple case: "(..." // This is an arrow function with a rest parameter. if (second === SyntaxKind.DotDotDotToken) { diff --git a/tests/baselines/reference/arrowFunctionExpressions.js b/tests/baselines/reference/arrowFunctionExpressions.js index 68516b52cb2..5e365291da7 100644 --- a/tests/baselines/reference/arrowFunctionExpressions.js +++ b/tests/baselines/reference/arrowFunctionExpressions.js @@ -13,6 +13,17 @@ var d = n => c = n; var d = (n) => c = n; var d: (n: any) => any; +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +var p2 = ([...a]) => { }; +var p3 = ([, a]) => { }; +var p4 = ([, ...a]) => { }; +var p5 = ([a = 1]) => { }; +var p6 = ({ a }) => { }; +var p7 = ({ a: { b } }) => { }; +var p8 = ({ a = 1 }) => { }; +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +var p10 = ([{ value, done }]) => { }; // Arrow function used in class member initializer // Arrow function used in class member function @@ -100,6 +111,37 @@ var c; var d = function (n) { return c = n; }; var d = function (n) { return c = n; }; var d; +// Binding patterns in arrow functions +var p1 = function (_a) { + var a = _a[0]; +}; +var p2 = function (_a) { + var a = _a.slice(0); +}; +var p3 = function (_a) { + var a = _a[1]; +}; +var p4 = function (_a) { + var a = _a.slice(1); +}; +var p5 = function (_a) { + var _b = _a[0], a = _b === void 0 ? 1 : _b; +}; +var p6 = function (_a) { + var a = _a.a; +}; +var p7 = function (_a) { + var b = _a.a.b; +}; +var p8 = function (_a) { + var _b = _a.a, a = _b === void 0 ? 1 : _b; +}; +var p9 = function (_a) { + var _b = _a.a, _c = (_b === void 0 ? { b: 1 } : _b).b, b = _c === void 0 ? 1 : _c; +}; +var p10 = function (_a) { + var _b = _a[0], value = _b.value, done = _b.done; +}; // Arrow function used in class member initializer // Arrow function used in class member function var MyClass = (function () { diff --git a/tests/baselines/reference/arrowFunctionExpressions.types b/tests/baselines/reference/arrowFunctionExpressions.types index 5807f6d6a7d..c10ecdad353 100644 --- a/tests/baselines/reference/arrowFunctionExpressions.types +++ b/tests/baselines/reference/arrowFunctionExpressions.types @@ -51,6 +51,61 @@ var d: (n: any) => any; >d : (n: any) => any >n : any +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +>p1 : ([a]: [any]) => void +>([a]) => { } : ([a]: [any]) => void +>a : any + +var p2 = ([...a]) => { }; +>p2 : ([...a]: any[]) => void +>([...a]) => { } : ([...a]: any[]) => void +>a : any[] + +var p3 = ([, a]) => { }; +>p3 : ([, a]: [any, any]) => void +>([, a]) => { } : ([, a]: [any, any]) => void +>a : any + +var p4 = ([, ...a]) => { }; +>p4 : ([, ...a]: any[]) => void +>([, ...a]) => { } : ([, ...a]: any[]) => void +>a : any[] + +var p5 = ([a = 1]) => { }; +>p5 : ([a = 1]: [number]) => void +>([a = 1]) => { } : ([a = 1]: [number]) => void +>a : number + +var p6 = ({ a }) => { }; +>p6 : ({ a }: { a: any; }) => void +>({ a }) => { } : ({ a }: { a: any; }) => void +>a : any + +var p7 = ({ a: { b } }) => { }; +>p7 : ({ a: { b } }: { a: { b: any; }; }) => void +>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void +>a : unknown +>b : any + +var p8 = ({ a = 1 }) => { }; +>p8 : ({ a = 1 }: { a?: number; }) => void +>({ a = 1 }) => { } : ({ a = 1 }: { a?: number; }) => void +>a : number + +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +>p9 : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void +>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void +>a : unknown +>b : number +>{ b: 1 } : { b: number; } +>b : number + +var p10 = ([{ value, done }]) => { }; +>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void +>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void +>value : any +>done : any // Arrow function used in class member initializer // Arrow function used in class member function diff --git a/tests/baselines/reference/emitArrowFunctionES6.js b/tests/baselines/reference/emitArrowFunctionES6.js index 603b2737fc5..f9f5669c92e 100644 --- a/tests/baselines/reference/emitArrowFunctionES6.js +++ b/tests/baselines/reference/emitArrowFunctionES6.js @@ -6,6 +6,18 @@ var f4 = (x: string, y: number, z=10) => { } function foo(func: () => boolean) { } foo(() => true); foo(() => { return false; }); + +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +var p2 = ([...a]) => { }; +var p3 = ([, a]) => { }; +var p4 = ([, ...a]) => { }; +var p5 = ([a = 1]) => { }; +var p6 = ({ a }) => { }; +var p7 = ({ a: { b } }) => { }; +var p8 = ({ a = 1 }) => { }; +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +var p10 = ([{ value, done }]) => { }; //// [emitArrowFunctionES6.js] @@ -16,3 +28,14 @@ var f4 = (x, y, z = 10) => { }; function foo(func) { } foo(() => true); foo(() => { return false; }); +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +var p2 = ([...a]) => { }; +var p3 = ([, a]) => { }; +var p4 = ([, ...a]) => { }; +var p5 = ([a = 1]) => { }; +var p6 = ({ a }) => { }; +var p7 = ({ a: { b } }) => { }; +var p8 = ({ a = 1 }) => { }; +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +var p10 = ([{ value, done }]) => { }; diff --git a/tests/baselines/reference/emitArrowFunctionES6.types b/tests/baselines/reference/emitArrowFunctionES6.types index 1f0c1941bdb..6f47b51a167 100644 --- a/tests/baselines/reference/emitArrowFunctionES6.types +++ b/tests/baselines/reference/emitArrowFunctionES6.types @@ -37,3 +37,59 @@ foo(() => { return false; }); >foo : (func: () => boolean) => void >() => { return false; } : () => boolean +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +>p1 : ([a]: [any]) => void +>([a]) => { } : ([a]: [any]) => void +>a : any + +var p2 = ([...a]) => { }; +>p2 : ([...a]: Iterable) => void +>([...a]) => { } : ([...a]: Iterable) => void +>a : any[] + +var p3 = ([, a]) => { }; +>p3 : ([, a]: [any, any]) => void +>([, a]) => { } : ([, a]: [any, any]) => void +>a : any + +var p4 = ([, ...a]) => { }; +>p4 : ([, ...a]: Iterable) => void +>([, ...a]) => { } : ([, ...a]: Iterable) => void +>a : any[] + +var p5 = ([a = 1]) => { }; +>p5 : ([a = 1]: [number]) => void +>([a = 1]) => { } : ([a = 1]: [number]) => void +>a : number + +var p6 = ({ a }) => { }; +>p6 : ({ a }: { a: any; }) => void +>({ a }) => { } : ({ a }: { a: any; }) => void +>a : any + +var p7 = ({ a: { b } }) => { }; +>p7 : ({ a: { b } }: { a: { b: any; }; }) => void +>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void +>a : unknown +>b : any + +var p8 = ({ a = 1 }) => { }; +>p8 : ({ a = 1 }: { a?: number; }) => void +>({ a = 1 }) => { } : ({ a = 1 }: { a?: number; }) => void +>a : number + +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +>p9 : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void +>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b = 1 } = { b: 1 } }: { a?: { b: number; }; }) => void +>a : unknown +>b : number +>{ b: 1 } : { b: number; } +>b : number + +var p10 = ([{ value, done }]) => { }; +>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void +>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void +>value : any +>done : any + diff --git a/tests/cases/conformance/es6/arrowFunction/emitArrowFunctionES6.ts b/tests/cases/conformance/es6/arrowFunction/emitArrowFunctionES6.ts index d56d07c6c4e..9dff987cd64 100644 --- a/tests/cases/conformance/es6/arrowFunction/emitArrowFunctionES6.ts +++ b/tests/cases/conformance/es6/arrowFunction/emitArrowFunctionES6.ts @@ -6,3 +6,15 @@ var f4 = (x: string, y: number, z=10) => { } function foo(func: () => boolean) { } foo(() => true); foo(() => { return false; }); + +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +var p2 = ([...a]) => { }; +var p3 = ([, a]) => { }; +var p4 = ([, ...a]) => { }; +var p5 = ([a = 1]) => { }; +var p6 = ({ a }) => { }; +var p7 = ({ a: { b } }) => { }; +var p8 = ({ a = 1 }) => { }; +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +var p10 = ([{ value, done }]) => { }; diff --git a/tests/cases/conformance/expressions/functions/arrowFunctionExpressions.ts b/tests/cases/conformance/expressions/functions/arrowFunctionExpressions.ts index a0d3b46bf43..707ef02de82 100644 --- a/tests/cases/conformance/expressions/functions/arrowFunctionExpressions.ts +++ b/tests/cases/conformance/expressions/functions/arrowFunctionExpressions.ts @@ -12,6 +12,17 @@ var d = n => c = n; var d = (n) => c = n; var d: (n: any) => any; +// Binding patterns in arrow functions +var p1 = ([a]) => { }; +var p2 = ([...a]) => { }; +var p3 = ([, a]) => { }; +var p4 = ([, ...a]) => { }; +var p5 = ([a = 1]) => { }; +var p6 = ({ a }) => { }; +var p7 = ({ a: { b } }) => { }; +var p8 = ({ a = 1 }) => { }; +var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; +var p10 = ([{ value, done }]) => { }; // Arrow function used in class member initializer // Arrow function used in class member function