From 96e5bd26c3e43a52d37a8e75a36fb385ca058864 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 11 Sep 2014 15:48:24 -0700 Subject: [PATCH 1/2] Fixed bug where function type literals may omit their '=>'. --- src/compiler/parser.ts | 13 ++++++++++++- .../functionTypesLackingReturnTypes.errors.txt | 18 ++++++++++++++++++ .../functionTypesLackingReturnTypes.ts | 13 +++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/functionTypesLackingReturnTypes.errors.txt create mode 100644 tests/cases/compiler/functionTypesLackingReturnTypes.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cfe27e7e7c3..8b44bdab60c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1274,7 +1274,18 @@ module ts { var typeParameters = parseTypeParameters(); var parameters = parseParameterList(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken); checkParameterList(parameters); - var type = parseOptional(returnToken) ? parseType() : undefined; + + var type: TypeNode; + + if (returnToken === SyntaxKind.EqualsGreaterThanToken) { + parseExpected(returnToken); + type = parseType(); + } + else if (parseOptional(returnToken)) + { + type = parseType(); + } + return { typeParameters: typeParameters, parameters: parameters, diff --git a/tests/baselines/reference/functionTypesLackingReturnTypes.errors.txt b/tests/baselines/reference/functionTypesLackingReturnTypes.errors.txt new file mode 100644 index 00000000000..289f5d11d43 --- /dev/null +++ b/tests/baselines/reference/functionTypesLackingReturnTypes.errors.txt @@ -0,0 +1,18 @@ +==== tests/cases/compiler/functionTypesLackingReturnTypes.ts (2 errors) ==== + + // Error (no '=>') + function f(x: ()) { + ~ +!!! '=>' expected. + } + + // Error (no '=>') + var g: (param); + ~ +!!! '=>' expected. + + // Okay + var h: { () } + + // Okay + var i: { new () } \ No newline at end of file diff --git a/tests/cases/compiler/functionTypesLackingReturnTypes.ts b/tests/cases/compiler/functionTypesLackingReturnTypes.ts new file mode 100644 index 00000000000..f1dac471287 --- /dev/null +++ b/tests/cases/compiler/functionTypesLackingReturnTypes.ts @@ -0,0 +1,13 @@ + +// Error (no '=>') +function f(x: ()) { +} + +// Error (no '=>') +var g: (param); + +// Okay +var h: { () } + +// Okay +var i: { new () } \ No newline at end of file From 5e7e5c5f515cccf71b48496ea3786cb752160b24 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 12 Sep 2014 13:07:57 -0700 Subject: [PATCH 2/2] Addressed CR feedback. --- src/compiler/parser.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8b44bdab60c..a3eedb29c61 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1267,7 +1267,7 @@ module ts { return finishNode(node); } - function parseSignature(kind: SyntaxKind, returnToken: SyntaxKind): ParsedSignature { + function parseSignature(kind: SyntaxKind, returnToken: SyntaxKind, returnTokenRequired: boolean): ParsedSignature { if (kind === SyntaxKind.ConstructSignature) { parseExpected(SyntaxKind.NewKeyword); } @@ -1277,7 +1277,7 @@ module ts { var type: TypeNode; - if (returnToken === SyntaxKind.EqualsGreaterThanToken) { + if (returnTokenRequired) { parseExpected(returnToken); type = parseType(); } @@ -1349,7 +1349,7 @@ module ts { function parseSignatureMember(kind: SyntaxKind, returnToken: SyntaxKind): SignatureDeclaration { var node = createNode(kind); - var sig = parseSignature(kind, returnToken); + var sig = parseSignature(kind, returnToken, /* returnTokenRequired */ false); node.typeParameters = sig.typeParameters; node.parameters = sig.parameters; node.type = sig.type; @@ -1422,7 +1422,7 @@ module ts { } if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { node.kind = SyntaxKind.Method; - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); (node).typeParameters = sig.typeParameters; (node).parameters = sig.parameters; (node).type = sig.type; @@ -1483,7 +1483,7 @@ module ts { function parseFunctionType(signatureKind: SyntaxKind): TypeLiteralNode { var node = createNode(SyntaxKind.TypeLiteral); var member = createNode(signatureKind); - var sig = parseSignature(signatureKind, SyntaxKind.EqualsGreaterThanToken); + var sig = parseSignature(signatureKind, SyntaxKind.EqualsGreaterThanToken, /* returnTokenRequired */ true); member.typeParameters = sig.typeParameters; member.parameters = sig.parameters; member.type = sig.type; @@ -1739,7 +1739,7 @@ module ts { var pos = getNodePos(); if (triState === Tristate.True) { - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); // If we have an arrow, then try to parse the body. // Even if not, try to parse if we have an opening brace, just in case we're in an error state. @@ -1842,7 +1842,7 @@ module ts { function tryParseSignatureIfArrowOrBraceFollows(): ParsedSignature { return tryParse(() => { - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); // Parsing a signature isn't enough. // Parenthesized arrow signatures often look like other valid expressions. @@ -2184,7 +2184,7 @@ module ts { var node = createNode(SyntaxKind.PropertyAssignment); node.name = parsePropertyName(); if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); var body = parseBody(/* ignoreMissingOpenBrace */ false); // do not propagate property name as name for function expression // for scenarios like @@ -2284,7 +2284,7 @@ module ts { var pos = getNodePos(); parseExpected(SyntaxKind.FunctionKeyword); var name = isIdentifier() ? parseIdentifier() : undefined; - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); var body = parseBody(/* ignoreMissingOpenBrace */ false); if (name && isInStrictMode && isEvalOrArgumentsIdentifier(name)) { // It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the @@ -2899,7 +2899,7 @@ module ts { if (flags) node.flags = flags; parseExpected(SyntaxKind.FunctionKeyword); node.name = parseIdentifier(); - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); node.typeParameters = sig.typeParameters; node.parameters = sig.parameters; node.type = sig.type; @@ -2916,7 +2916,7 @@ module ts { var node = createNode(SyntaxKind.Constructor, pos); node.flags = flags; parseExpected(SyntaxKind.ConstructorKeyword); - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); node.typeParameters = sig.typeParameters; node.parameters = sig.parameters; node.type = sig.type; @@ -2943,7 +2943,7 @@ module ts { var method = createNode(SyntaxKind.Method, pos); method.flags = flags; method.name = name; - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); method.typeParameters = sig.typeParameters; method.parameters = sig.parameters; method.type = sig.type; @@ -3016,7 +3016,7 @@ module ts { var node = createNode(kind, pos); node.flags = flags; node.name = parsePropertyName(); - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false); node.typeParameters = sig.typeParameters; node.parameters = sig.parameters; node.type = sig.type;