Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2450,33 +2450,49 @@ namespace ts {
if (token === SyntaxKind.LessThanToken) {
return true;
}

return token === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType);
}

function skipParameterStart(): boolean {
if (isModifierKind(token)) {
// Skip modifiers
parseModifiers();
}
if (isIdentifier()) {
nextToken();
return true;
}
if (token === SyntaxKind.OpenBracketToken || token === SyntaxKind.OpenBraceToken) {
// Return true if we can parse an array or object binding pattern with no errors
const previousErrorCount = parseDiagnostics.length;
parseIdentifierOrPattern();
return previousErrorCount === parseDiagnostics.length;
}
return false;
}

function isUnambiguouslyStartOfFunctionType() {
nextToken();
if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) {
// ( )
// ( ...
return true;
}
if (isIdentifier() || isModifierKind(token)) {
nextToken();
if (skipParameterStart()) {
// We successfully skipped modifiers (if any) and an identifier or binding pattern,
// now see if we have something that indicates a parameter declaration
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
isIdentifier() || isModifierKind(token)) {
// ( id :
// ( id ,
// ( id ?
// ( id =
// ( modifier id
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken) {
// ( xxx :
// ( xxx ,
// ( xxx ?
// ( xxx =
return true;
}
if (token === SyntaxKind.CloseParenToken) {
nextToken();
if (token === SyntaxKind.EqualsGreaterThanToken) {
// ( id ) =>
// ( xxx ) =>
return true;
}
}
Expand Down
61 changes: 61 additions & 0 deletions tests/baselines/reference/destructuringInFunctionType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//// [destructuringInFunctionType.ts]

interface a { a }
interface b { b }
interface c { c }

type T1 = ([a, b, c]);
type F1 = ([a, b, c]) => void;

type T2 = ({ a });
type F2 = ({ a }) => void;

type T3 = ([{ a: b }, { b: a }]);
type F3 = ([{ a: b }, { b: a }]) => void;

type T4 = ([{ a: [b, c] }]);
type F4 = ([{ a: [b, c] }]) => void;

type C1 = new ([{ a: [b, c] }]) => void;

var v1 = ([a, b, c]) => "hello";
var v2: ([a, b, c]) => string;


//// [destructuringInFunctionType.js]
var v1 = function (_a) {
var a = _a[0], b = _a[1], c = _a[2];
return "hello";
};
var v2;


//// [destructuringInFunctionType.d.ts]
interface a {
a: any;
}
interface b {
b: any;
}
interface c {
c: any;
}
declare type T1 = ([a, b, c]);
declare type F1 = ([a, b, c]) => void;
declare type T2 = ({
a;
});
declare type F2 = ({a}) => void;
declare type T3 = ([{
a: b;
}, {
b: a;
}]);
declare type F3 = ([{a: b}, {b: a}]) => void;
declare type T4 = ([{
a: [b, c];
}]);
declare type F4 = ([{a: [b, c]}]) => void;
declare type C1 = new ([{a: [b, c]}]) => void;
declare var v1: ([a, b, c]: [any, any, any]) => string;
declare var v2: ([a, b, c]) => string;
78 changes: 78 additions & 0 deletions tests/baselines/reference/destructuringInFunctionType.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
=== tests/cases/conformance/es6/destructuring/destructuringInFunctionType.ts ===

interface a { a }
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 1, 13))

interface b { b }
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 2, 13))

interface c { c }
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 3, 13))

type T1 = ([a, b, c]);
>T1 : Symbol(T1, Decl(destructuringInFunctionType.ts, 3, 17))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))

type F1 = ([a, b, c]) => void;
>F1 : Symbol(F1, Decl(destructuringInFunctionType.ts, 5, 22))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 6, 12))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 6, 14))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 6, 17))

type T2 = ({ a });
>T2 : Symbol(T2, Decl(destructuringInFunctionType.ts, 6, 30))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 8, 12))

type F2 = ({ a }) => void;
>F2 : Symbol(F2, Decl(destructuringInFunctionType.ts, 8, 18))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 9, 12))

type T3 = ([{ a: b }, { b: a }]);
>T3 : Symbol(T3, Decl(destructuringInFunctionType.ts, 9, 26))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 11, 13))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 11, 23))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))

type F3 = ([{ a: b }, { b: a }]) => void;
>F3 : Symbol(F3, Decl(destructuringInFunctionType.ts, 11, 33))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 12, 13))
>b : Symbol(b)
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 12, 23))

type T4 = ([{ a: [b, c] }]);
>T4 : Symbol(T4, Decl(destructuringInFunctionType.ts, 12, 41))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 14, 13))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))

type F4 = ([{ a: [b, c] }]) => void;
>F4 : Symbol(F4, Decl(destructuringInFunctionType.ts, 14, 28))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 15, 18))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 15, 20))

type C1 = new ([{ a: [b, c] }]) => void;
>C1 : Symbol(C1, Decl(destructuringInFunctionType.ts, 15, 36))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 17, 22))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 17, 24))

var v1 = ([a, b, c]) => "hello";
>v1 : Symbol(v1, Decl(destructuringInFunctionType.ts, 19, 3))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 19, 11))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 19, 13))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 19, 16))

var v2: ([a, b, c]) => string;
>v2 : Symbol(v2, Decl(destructuringInFunctionType.ts, 20, 3))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 20, 10))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 20, 12))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 20, 15))

80 changes: 80 additions & 0 deletions tests/baselines/reference/destructuringInFunctionType.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
=== tests/cases/conformance/es6/destructuring/destructuringInFunctionType.ts ===

interface a { a }
>a : a
>a : any

interface b { b }
>b : b
>b : any

interface c { c }
>c : c
>c : any

type T1 = ([a, b, c]);
>T1 : [a, b, c]
>a : a
>b : b
>c : c

type F1 = ([a, b, c]) => void;
>F1 : ([a, b, c]: [any, any, any]) => void
>a : any
>b : any
>c : any

type T2 = ({ a });
>T2 : { a: any; }
>a : any

type F2 = ({ a }) => void;
>F2 : ({ a }: { a: any; }) => void
>a : any

type T3 = ([{ a: b }, { b: a }]);
>T3 : [{ a: b; }, { b: a; }]
>a : b
>b : b
>b : a
>a : a

type F3 = ([{ a: b }, { b: a }]) => void;
>F3 : ([{ a: b }, { b: a }]: [{ a: any; }, { b: any; }]) => void
>a : any
>b : any
>b : any
>a : any

type T4 = ([{ a: [b, c] }]);
>T4 : [{ a: [b, c]; }]
>a : [b, c]
>b : b
>c : c

type F4 = ([{ a: [b, c] }]) => void;
>F4 : ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
>a : any
>b : any
>c : any

type C1 = new ([{ a: [b, c] }]) => void;
>C1 : new ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
>a : any
>b : any
>c : any

var v1 = ([a, b, c]) => "hello";
>v1 : ([a, b, c]: [any, any, any]) => string
>([a, b, c]) => "hello" : ([a, b, c]: [any, any, any]) => string
>a : any
>b : any
>c : any
>"hello" : string

var v2: ([a, b, c]) => string;
>v2 : ([a, b, c]: [any, any, any]) => string
>a : any
>b : any
>c : any

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @declaration: true

interface a { a }
interface b { b }
interface c { c }

type T1 = ([a, b, c]);
type F1 = ([a, b, c]) => void;

type T2 = ({ a });
type F2 = ({ a }) => void;

type T3 = ([{ a: b }, { b: a }]);
type F3 = ([{ a: b }, { b: a }]) => void;

type T4 = ([{ a: [b, c] }]);
type F4 = ([{ a: [b, c] }]) => void;

type C1 = new ([{ a: [b, c] }]) => void;

var v1 = ([a, b, c]) => "hello";
var v2: ([a, b, c]) => string;