diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cfe27e7e7c3..a3eedb29c61 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1267,14 +1267,25 @@ 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); } var typeParameters = parseTypeParameters(); var parameters = parseParameterList(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken); checkParameterList(parameters); - var type = parseOptional(returnToken) ? parseType() : undefined; + + var type: TypeNode; + + if (returnTokenRequired) { + parseExpected(returnToken); + type = parseType(); + } + else if (parseOptional(returnToken)) + { + type = parseType(); + } + return { typeParameters: typeParameters, parameters: parameters, @@ -1338,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; @@ -1411,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; @@ -1472,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; @@ -1728,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. @@ -1831,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. @@ -2173,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 @@ -2273,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 @@ -2888,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; @@ -2905,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; @@ -2932,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; @@ -3005,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; 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