Move grammar checking: type parameters

This commit is contained in:
Yui T
2014-12-09 16:33:20 -08:00
parent bb70e9eb12
commit 2c575dae27
5 changed files with 53 additions and 11 deletions

View File

@@ -164,6 +164,13 @@ module ts {
var diagnostics: Diagnostic[] = [];
var diagnosticsModified: boolean = false;
// Grammar checking
var sourceText: string = undefined;
var scanner: Scanner = undefined;
var hasParserError: boolean;
var grammarDiagnostics: Diagnostic[];
var sourceFile: SourceFile;
function addDiagnostic(diagnostic: Diagnostic) {
diagnostics.push(diagnostic);
diagnosticsModified = true;
@@ -7017,6 +7024,11 @@ module ts {
// DECLARATION AND STATEMENT TYPE CHECKING
function checkTypeParameter(node: TypeParameterDeclaration) {
// Grammar Checking
if (!hasParserError && node.expression) {
grammarErrorOnFirstToken(node.expression, Diagnostics.Type_expected);
}
checkSourceElement(node.constraint);
if (fullTypeCheck) {
checkTypeParameterHasIllegalReferencesInConstraint(node);
@@ -8655,6 +8667,36 @@ module ts {
return <Identifier>node;
}
// Grammar checking helper functions
function scanToken(pos: number) {
var start = skipTrivia(sourceText, pos);
scanner.setTextPos(start);
scanner.scan();
return start;
}
function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
var start = scanToken(node.pos);
diagnostics.push(createFileDiagnostic(sourceFile, start, scanner.getTextPos() - start, message, arg0, arg1, arg2));
}
function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
scanToken(node.pos);
diagnostics.push(createFileDiagnostic(sourceFile, scanner.getTextPos(), 0, message, arg0, arg1, arg2));
}
function grammarErrorOnNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
var span = getErrorSpanForNode(node);
var start = span.end > span.pos ? skipTrivia(sourceFile.text, span.pos) : span.pos;
var length = span.end - start;
diagnostics.push(createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
}
function grammarErrorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
diagnostics.push(createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
}
function checkImportDeclaration(node: ImportDeclaration) {
checkCollisionWithCapturedThisVariable(node, node.name);
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
@@ -8909,6 +8951,12 @@ module ts {
// Fully type check a source file and collect the relevant diagnostics.
function checkSourceFile(node: SourceFile) {
sourceText = node.text;
scanner = createScanner(compilerOptions.target, /*skipTrivia*/ true, sourceText);
hasParserError = node.parseDiagnostics.length > 0 ? true : false;
sourceFile = node;
//grammarDiagnostics = [];
var links = getNodeLinks(node);
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
emitExtends = false;
@@ -9469,7 +9517,7 @@ module ts {
return program.getDiagnostics(sourceFile).length !== 0 ||
hasEarlyErrors(sourceFile) ||
(compilerOptions.noEmitOnError && getDiagnostics(sourceFile).length !== 0);
}
}
function hasEarlyErrors(sourceFile?: SourceFile): boolean {
return forEach(getDiagnostics(sourceFile), d => d.isEarly);

View File

@@ -73,7 +73,7 @@ module ts {
Jump_target_cannot_cross_function_boundary: { code: 1107, category: DiagnosticCategory.Error, key: "Jump target cannot cross function boundary." },
A_return_statement_can_only_be_used_within_a_function_body: { code: 1108, category: DiagnosticCategory.Error, key: "A 'return' statement can only be used within a function body." },
Expression_expected: { code: 1109, category: DiagnosticCategory.Error, key: "Expression expected." },
Type_expected: { code: 1110, category: DiagnosticCategory.Error, key: "Type expected." },
Type_expected: { code: 1110, category: DiagnosticCategory.Error, key: "Type expected.", isEarly: true },
A_constructor_implementation_cannot_be_declared_in_an_ambient_context: { code: 1111, category: DiagnosticCategory.Error, key: "A constructor implementation cannot be declared in an ambient context." },
A_class_member_cannot_be_declared_optional: { code: 1112, category: DiagnosticCategory.Error, key: "A class member cannot be declared optional." },
A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: { code: 1113, category: DiagnosticCategory.Error, key: "A 'default' clause cannot appear more than once in a 'switch' statement." },

View File

@@ -285,7 +285,8 @@
},
"Type expected.": {
"category": "Error",
"code": 1110
"code": 1110,
"isEarly": true
},
"A constructor implementation cannot be declared in an ambient context.": {
"category": "Error",

View File

@@ -4679,7 +4679,6 @@ module ts {
case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.ThrowStatement: return checkThrowStatement(<ThrowStatement>node);
case SyntaxKind.TupleType: return checkTupleType(<TupleTypeNode>node);
case SyntaxKind.TypeParameter: return checkTypeParameter(<TypeParameterDeclaration>node);
case SyntaxKind.TypeReference: return checkTypeReference(<TypeReferenceNode>node);
case SyntaxKind.VariableDeclaration: return checkVariableDeclaration(<VariableDeclaration>node);
case SyntaxKind.VariableStatement: return checkVariableStatement(<VariableStatement>node);
@@ -5727,12 +5726,6 @@ module ts {
}
}
function checkTypeParameter(node: TypeParameterDeclaration) {
if (node.expression) {
return grammarErrorOnFirstToken(node.expression, Diagnostics.Type_expected);
}
}
function checkTypeReference(node: TypeReferenceNode) {
return checkTypeArguments(node.typeArguments);
}

View File

@@ -1,8 +1,8 @@
tests/cases/compiler/typeParameterConstraints1.ts(6,25): error TS2304: Cannot find name 'hm'.
tests/cases/compiler/typeParameterConstraints1.ts(8,25): error TS1110: Type expected.
tests/cases/compiler/typeParameterConstraints1.ts(9,25): error TS1110: Type expected.
tests/cases/compiler/typeParameterConstraints1.ts(10,26): error TS1110: Type expected.
tests/cases/compiler/typeParameterConstraints1.ts(11,26): error TS1110: Type expected.
tests/cases/compiler/typeParameterConstraints1.ts(6,25): error TS2304: Cannot find name 'hm'.
tests/cases/compiler/typeParameterConstraints1.ts(12,26): error TS2304: Cannot find name 'undefined'.