Skip to content

Commit c277db0

Browse files
Merge pull request #659 from Microsoft/functionTypeLiteralsNeedArrows
Fixed bug where function type literals may omit their '=>'.
2 parents 2ba3ae9 + 5e7e5c5 commit c277db0

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

src/compiler/parser.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,14 +1267,25 @@ module ts {
12671267
return finishNode(node);
12681268
}
12691269

1270-
function parseSignature(kind: SyntaxKind, returnToken: SyntaxKind): ParsedSignature {
1270+
function parseSignature(kind: SyntaxKind, returnToken: SyntaxKind, returnTokenRequired: boolean): ParsedSignature {
12711271
if (kind === SyntaxKind.ConstructSignature) {
12721272
parseExpected(SyntaxKind.NewKeyword);
12731273
}
12741274
var typeParameters = parseTypeParameters();
12751275
var parameters = parseParameterList(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken);
12761276
checkParameterList(parameters);
1277-
var type = parseOptional(returnToken) ? parseType() : undefined;
1277+
1278+
var type: TypeNode;
1279+
1280+
if (returnTokenRequired) {
1281+
parseExpected(returnToken);
1282+
type = parseType();
1283+
}
1284+
else if (parseOptional(returnToken))
1285+
{
1286+
type = parseType();
1287+
}
1288+
12781289
return {
12791290
typeParameters: typeParameters,
12801291
parameters: parameters,
@@ -1338,7 +1349,7 @@ module ts {
13381349

13391350
function parseSignatureMember(kind: SyntaxKind, returnToken: SyntaxKind): SignatureDeclaration {
13401351
var node = <SignatureDeclaration>createNode(kind);
1341-
var sig = parseSignature(kind, returnToken);
1352+
var sig = parseSignature(kind, returnToken, /* returnTokenRequired */ false);
13421353
node.typeParameters = sig.typeParameters;
13431354
node.parameters = sig.parameters;
13441355
node.type = sig.type;
@@ -1411,7 +1422,7 @@ module ts {
14111422
}
14121423
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
14131424
node.kind = SyntaxKind.Method;
1414-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
1425+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
14151426
(<MethodDeclaration>node).typeParameters = sig.typeParameters;
14161427
(<MethodDeclaration>node).parameters = sig.parameters;
14171428
(<MethodDeclaration>node).type = sig.type;
@@ -1472,7 +1483,7 @@ module ts {
14721483
function parseFunctionType(signatureKind: SyntaxKind): TypeLiteralNode {
14731484
var node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
14741485
var member = <SignatureDeclaration>createNode(signatureKind);
1475-
var sig = parseSignature(signatureKind, SyntaxKind.EqualsGreaterThanToken);
1486+
var sig = parseSignature(signatureKind, SyntaxKind.EqualsGreaterThanToken, /* returnTokenRequired */ true);
14761487
member.typeParameters = sig.typeParameters;
14771488
member.parameters = sig.parameters;
14781489
member.type = sig.type;
@@ -1728,7 +1739,7 @@ module ts {
17281739
var pos = getNodePos();
17291740

17301741
if (triState === Tristate.True) {
1731-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
1742+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
17321743

17331744
// If we have an arrow, then try to parse the body.
17341745
// Even if not, try to parse if we have an opening brace, just in case we're in an error state.
@@ -1831,7 +1842,7 @@ module ts {
18311842

18321843
function tryParseSignatureIfArrowOrBraceFollows(): ParsedSignature {
18331844
return tryParse(() => {
1834-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
1845+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
18351846

18361847
// Parsing a signature isn't enough.
18371848
// Parenthesized arrow signatures often look like other valid expressions.
@@ -2173,7 +2184,7 @@ module ts {
21732184
var node = <PropertyDeclaration>createNode(SyntaxKind.PropertyAssignment);
21742185
node.name = parsePropertyName();
21752186
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
2176-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
2187+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
21772188
var body = parseBody(/* ignoreMissingOpenBrace */ false);
21782189
// do not propagate property name as name for function expression
21792190
// for scenarios like
@@ -2273,7 +2284,7 @@ module ts {
22732284
var pos = getNodePos();
22742285
parseExpected(SyntaxKind.FunctionKeyword);
22752286
var name = isIdentifier() ? parseIdentifier() : undefined;
2276-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
2287+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
22772288
var body = parseBody(/* ignoreMissingOpenBrace */ false);
22782289
if (name && isInStrictMode && isEvalOrArgumentsIdentifier(name)) {
22792290
// It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the
@@ -2888,7 +2899,7 @@ module ts {
28882899
if (flags) node.flags = flags;
28892900
parseExpected(SyntaxKind.FunctionKeyword);
28902901
node.name = parseIdentifier();
2891-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
2902+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
28922903
node.typeParameters = sig.typeParameters;
28932904
node.parameters = sig.parameters;
28942905
node.type = sig.type;
@@ -2905,7 +2916,7 @@ module ts {
29052916
var node = <ConstructorDeclaration>createNode(SyntaxKind.Constructor, pos);
29062917
node.flags = flags;
29072918
parseExpected(SyntaxKind.ConstructorKeyword);
2908-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
2919+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
29092920
node.typeParameters = sig.typeParameters;
29102921
node.parameters = sig.parameters;
29112922
node.type = sig.type;
@@ -2932,7 +2943,7 @@ module ts {
29322943
var method = <MethodDeclaration>createNode(SyntaxKind.Method, pos);
29332944
method.flags = flags;
29342945
method.name = name;
2935-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
2946+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
29362947
method.typeParameters = sig.typeParameters;
29372948
method.parameters = sig.parameters;
29382949
method.type = sig.type;
@@ -3005,7 +3016,7 @@ module ts {
30053016
var node = <MethodDeclaration>createNode(kind, pos);
30063017
node.flags = flags;
30073018
node.name = parsePropertyName();
3008-
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
3019+
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false);
30093020
node.typeParameters = sig.typeParameters;
30103021
node.parameters = sig.parameters;
30113022
node.type = sig.type;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
==== tests/cases/compiler/functionTypesLackingReturnTypes.ts (2 errors) ====
2+
3+
// Error (no '=>')
4+
function f(x: ()) {
5+
~
6+
!!! '=>' expected.
7+
}
8+
9+
// Error (no '=>')
10+
var g: (param);
11+
~
12+
!!! '=>' expected.
13+
14+
// Okay
15+
var h: { () }
16+
17+
// Okay
18+
var i: { new () }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
// Error (no '=>')
3+
function f(x: ()) {
4+
}
5+
6+
// Error (no '=>')
7+
var g: (param);
8+
9+
// Okay
10+
var h: { () }
11+
12+
// Okay
13+
var i: { new () }

0 commit comments

Comments
 (0)