From 1a0f32213f885a55439348d4e89df5961b21f2a8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 19 Nov 2014 16:55:18 -0800 Subject: [PATCH] Move type parameter error handling code to the grammar checker. --- src/compiler/parser.ts | 27 ++++++------------- src/compiler/types.ts | 3 +++ .../typeParameterConstraints1.errors.txt | 2 +- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 696b3986c54..34b49c5b07d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -855,23 +855,6 @@ module ts { errorAtPos(start, length, message, arg0, arg1, arg2); } - // This is just like createDiagnosticForNode except that it uses the current file - // being parsed instead of the file containing the node. This is because during - // parse, the nodes do not have parent pointers to get to the file. - // - // It is very intentional that we are not checking or changing the lookAheadMode value - // here. 'grammarErrorOnNode' is called when we are doing extra grammar checks and not - // when we are doing the actual parsing to determine what the user wrote. In other - // words, this function is called once we have already parsed the node, and are just - // applying some stricter checks on that node. - function grammarErrorOnNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { - var span = getErrorSpanForNode(node); - var start = span.end > span.pos ? skipTrivia(file.text, span.pos) : span.pos; - var length = span.end - start; - - file.parseDiagnostics.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2)); - } - function grammarErrorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { file.parseDiagnostics.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2)); } @@ -1458,8 +1441,7 @@ module ts { // // // We do *not* want to consume the > as we're consuming the expression for "". - var expr = parseUnaryExpression(); - grammarErrorOnNode(expr, Diagnostics.Type_expected); + node.expression = parseUnaryExpression(); } } @@ -3762,6 +3744,7 @@ module ts { case SyntaxKind.SwitchStatement: return visitSwitchStatement(node); case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(node); case SyntaxKind.TupleType: return visitTupleType(node); + case SyntaxKind.TypeParameter: return visitTypeParameter(node); case SyntaxKind.TypeReference: return visitTypeReference(node); case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(node); case SyntaxKind.VariableStatement: return visitVariableStatement(node); @@ -4467,6 +4450,12 @@ module ts { } } + function visitTypeParameter(node: TypeParameterDeclaration) { + if (node.expression) { + grammarErrorOnFirstToken(node.expression, Diagnostics.Type_expected); + } + } + function visitTypeReference(node: TypeReferenceNode) { checkForAtLeastOneTypeArgument(node.typeArguments); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 81e2375780d..97db90ea048 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -326,6 +326,9 @@ module ts { export interface TypeParameterDeclaration extends Declaration { name: Identifier; constraint?: TypeNode; + + // For error recovery purposes. + expression?: Expression; } export interface SignatureDeclaration extends Declaration, ParsedSignature { } diff --git a/tests/baselines/reference/typeParameterConstraints1.errors.txt b/tests/baselines/reference/typeParameterConstraints1.errors.txt index e081f3c6ce6..d2e1f505c83 100644 --- a/tests/baselines/reference/typeParameterConstraints1.errors.txt +++ b/tests/baselines/reference/typeParameterConstraints1.errors.txt @@ -23,7 +23,7 @@ tests/cases/compiler/typeParameterConstraints1.ts(12,26): error TS2304: Cannot f ~ !!! error TS1110: Type expected. function foo10 (test: T) { } - ~~~ + ~ !!! error TS1110: Type expected. function foo11 (test: T) { } ~~~~