diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f94ac9a75c5..20f757c3df8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1316,14 +1316,12 @@ namespace ts { export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic; export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic { - const end = start + length; - Debug.assertGreaterThanOrEqual(start, 0); Debug.assertGreaterThanOrEqual(length, 0); if (file) { Debug.assertLessThanOrEqual(start, file.text.length); - Debug.assertLessThanOrEqual(end, file.text.length); + Debug.assertLessThanOrEqual(start + length, file.text.length); } let text = getLocaleSpecificMessage(message); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7486c7541be..d3cbf38522a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2290,25 +2290,27 @@ namespace ts { signature.typeParameters = parseTypeParameters(); } signature.parameters = parseParameterList(flags); + signature.type = parseReturnType(returnToken, !!(flags & SignatureFlags.Type)); + } - const returnTokenRequired = returnToken === SyntaxKind.EqualsGreaterThanToken; - if (returnTokenRequired) { + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined { + return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined; + } + function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { + if (returnToken === SyntaxKind.EqualsGreaterThanToken) { parseExpected(returnToken); - signature.type = parseTypeOrTypePredicate(); + return true; } - else if (parseOptional(returnToken)) { - signature.type = parseTypeOrTypePredicate(); + else if (parseOptional(SyntaxKind.ColonToken)) { + return true; } - else if (flags & SignatureFlags.Type) { - const start = scanner.getTokenPos(); - const length = scanner.getTextPos() - start; - const backwardToken = parseOptional(returnToken === SyntaxKind.ColonToken ? SyntaxKind.EqualsGreaterThanToken : SyntaxKind.ColonToken); - if (backwardToken) { - // This is easy to get backward, especially in type contexts, so parse the type anyway - signature.type = parseTypeOrTypePredicate(); - parseErrorAtPosition(start, length, Diagnostics._0_expected, tokenToString(returnToken)); - } + else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) { + // This is easy to get backward, especially in type contexts, so parse the type anyway + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); + nextToken(); + return true; } + return false; } function parseParameterList(flags: SignatureFlags) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 64444693acf..0d9bb8d50e8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -668,7 +668,7 @@ namespace ts { name?: PropertyName; typeParameters?: NodeArray; parameters: NodeArray; - type?: TypeNode; + type: TypeNode | undefined; } export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {