Move type argument tests to the grammar checker.

This commit is contained in:
Cyrus Najmabadi 2014-11-19 02:30:16 -08:00
parent 9170962998
commit 90cc44bb2f
2 changed files with 17 additions and 11 deletions

View File

@ -2457,18 +2457,12 @@ module ts {
}
function parseTypeArguments(): NodeArray<TypeNode> {
var typeArgumentListStart = scanner.getTokenPos();
var errorCountBeforeTypeParameterList = file._parserDiagnostics.length;
// We pass parseSingleTypeArgument instead of parseType as the element parser
// because parseSingleTypeArgument knows how to parse a missing type argument.
// This is useful for signature help. parseType has the disadvantage that when
// it sees a missing type, it changes the LookAheadMode to Error, and the result
// is a broken binary expression, which breaks signature help.
var result = parseBracketedList(ParsingContext.TypeArguments, parseSingleTypeArgument, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
if (!result.length && file._parserDiagnostics.length === errorCountBeforeTypeParameterList) {
grammarErrorAtPos(typeArgumentListStart, scanner.getStartPos() - typeArgumentListStart, Diagnostics.Type_argument_list_cannot_be_empty);
}
return result;
return parseBracketedList(ParsingContext.TypeArguments, parseSingleTypeArgument, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
}
function parseSingleTypeArgument(): TypeNode {
@ -4047,6 +4041,7 @@ module ts {
case SyntaxKind.SetAccessor: return visitSetAccessor(<MethodDeclaration>node);
case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.TupleType: return visitTupleType(<TupleTypeNode>node);
case SyntaxKind.TypeReference: return visitTypeReference(<TypeReferenceNode>node);
case SyntaxKind.VariableDeclaration: return visitVariableDeclaration(<VariableDeclaration>node);
case SyntaxKind.VariableStatement: return visitVariableStatement(<VariableStatement>node);
}
@ -4091,9 +4086,18 @@ module ts {
function visitCallExpression(node: CallExpression) {
checkForTrailingComma(node.typeArguments) ||
checkForAtLeastOneTypeArgument(node.typeArguments) ||
checkForTrailingComma(node.arguments);
}
function checkForAtLeastOneTypeArgument(typeArguments: NodeArray<TypeNode>) {
if (typeArguments && typeArguments.length === 0) {
var start = typeArguments.pos - "<".length;
var end = typeArguments.end + ">".length;
return grammarErrorAtPos(start, end - start, Diagnostics.Type_argument_list_cannot_be_empty);
}
}
function checkForTrailingComma(list: NodeArray<Node>): boolean {
if (list && list.hasTrailingComma) {
var start = list.end - ",".length;
@ -4307,6 +4311,7 @@ module ts {
function visitNewExpression(node: NewExpression): void {
checkForTrailingComma(node.typeArguments) ||
checkForAtLeastOneTypeArgument(node.typeArguments) ||
checkForTrailingComma(node.arguments);
}
@ -4520,6 +4525,10 @@ module ts {
checkForTrailingComma(node.elementTypes);
}
function visitTypeReference(node: TypeReferenceNode) {
checkForAtLeastOneTypeArgument(node.typeArguments);
}
function visitVariableDeclaration(node: VariableDeclaration) {
if (inAmbientContext && node.initializer) {
var equalsPos = node.type ? skipTrivia(sourceText, node.type.end) : skipTrivia(sourceText, node.name.end);

View File

@ -1,16 +1,13 @@
tests/cases/compiler/instantiateTypeParameter.ts(2,5): error TS1131: Property or signature expected.
tests/cases/compiler/instantiateTypeParameter.ts(2,13): error TS1099: Type argument list cannot be empty.
tests/cases/compiler/instantiateTypeParameter.ts(3,1): error TS1128: Declaration or statement expected.
tests/cases/compiler/instantiateTypeParameter.ts(2,12): error TS2304: Cannot find name 'T'.
==== tests/cases/compiler/instantiateTypeParameter.ts (4 errors) ====
==== tests/cases/compiler/instantiateTypeParameter.ts (3 errors) ====
interface Foo<T> {
var x: T<>;
~~~
!!! error TS1131: Property or signature expected.
~~
!!! error TS1099: Type argument list cannot be empty.
~~~
!!! error TS2304: Cannot find name 'T'.
}