diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 97c39dd8aaf..8c4cfeec5fa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8468,6 +8468,9 @@ module ts { } function checkInterfaceDeclaration(node: InterfaceDeclaration) { + // Grammar checking + checkGrammarInterfaceDeclaration(node); + checkTypeParameters(node.typeParameters); if (fullTypeCheck) { checkTypeNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0); @@ -10008,6 +10011,18 @@ module ts { } } + function checkGrammarHeritageClause(node: HeritageClause): boolean { + var types = node.types; + if (checkGrammarForDisallowedTrailingComma(types)) { + return true; + } + var listType = tokenToString(node.token); + if (types && types.length === 0) { + var sourceFile = getSourceFileOfNode(node); + return grammarErrorAtPos(sourceFile, types.pos, 0, Diagnostics._0_list_cannot_be_empty, listType) + } + } + function checkGrammarClassDeclarationHeritageClauses(node: ClassDeclaration) { var seenExtendsClause = false; var seenImplementsClause = false; @@ -10044,10 +10059,41 @@ module ts { seenImplementsClause = true; } + + // Grammar checking heritageClause inside class declaration + checkGrammarHeritageClause(heritageClause); } } } + function checkGrammarInterfaceDeclaration(node: InterfaceDeclaration) { + var seenExtendsClause = false; + + if (node.heritageClauses) { + for (var i = 0, n = node.heritageClauses.length; i < n; i++) { + Debug.assert(i <= 1); + var heritageClause = node.heritageClauses[i]; + + if (heritageClause.token === SyntaxKind.ExtendsKeyword) { + if (seenExtendsClause) { + return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_already_seen); + } + + seenExtendsClause = true; + } + else { + Debug.assert(heritageClause.token === SyntaxKind.ImplementsKeyword); + return grammarErrorOnFirstToken(heritageClause, Diagnostics.Interface_declaration_cannot_have_implements_clause); + } + + // Grammar checking heritageClause inside class declaration + checkGrammarHeritageClause(heritageClause); + } + } + + return false; + } + function checkGrammarComputedPropertyName(node: ComputedPropertyName): void { // Since computed properties are not supported in the type checker, disallow them in TypeScript 1.4 // Once full support is added, remove this error. diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c67d0e90ae4..7fb859f750a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4649,8 +4649,8 @@ module ts { case SyntaxKind.FunctionDeclaration: return checkFunctionDeclaration(node); //case SyntaxKind.FunctionExpression: return checkFunctionExpression(node); case SyntaxKind.GetAccessor: return checkGetAccessor(node); - case SyntaxKind.HeritageClause: return checkHeritageClause(node); - case SyntaxKind.InterfaceDeclaration: return checkInterfaceDeclaration(node); + //case SyntaxKind.HeritageClause: return checkHeritageClause(node); + //case SyntaxKind.InterfaceDeclaration: return checkInterfaceDeclaration(node); case SyntaxKind.LabeledStatement: return checkLabeledStatement(node); case SyntaxKind.PropertyAssignment: return checkPropertyAssignment(node); case SyntaxKind.MethodDeclaration: diff --git a/tests/baselines/reference/interfaceThatInheritsFromItself.errors.txt b/tests/baselines/reference/interfaceThatInheritsFromItself.errors.txt index 440650717bd..b1e47347117 100644 --- a/tests/baselines/reference/interfaceThatInheritsFromItself.errors.txt +++ b/tests/baselines/reference/interfaceThatInheritsFromItself.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts(10,15): error TS1176: Interface declaration cannot have 'implements' clause. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts(1,11): error TS2310: Type 'Foo' recursively references itself as a base type. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts(4,11): error TS2310: Type 'Foo2' recursively references itself as a base type. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts(7,11): error TS2310: Type 'Foo3' recursively references itself as a base type. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts(10,15): error TS1176: Interface declaration cannot have 'implements' clause. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatInheritsFromItself.ts (4 errors) ==== diff --git a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause2.errors.txt b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause2.errors.txt index 9e4d8b76d75..c3aee20c780 100644 --- a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause2.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause2.ts(1,18): error TS1009: Trailing comma not allowed. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause2.ts(1,17): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause2.ts(1,18): error TS1009: Trailing comma not allowed. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause2.ts (2 errors) ==== class C extends A, { - ~ -!!! error TS1009: Trailing comma not allowed. ~ !!! error TS2304: Cannot find name 'A'. + ~ +!!! error TS1009: Trailing comma not allowed. } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause4.errors.txt b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause4.errors.txt index 6d637831c45..aaf5b803267 100644 --- a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause4.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause4.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause4.ts(1,29): error TS1097: 'implements' list cannot be empty. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause4.ts(1,17): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause4.ts(1,29): error TS1097: 'implements' list cannot be empty. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause4.ts (2 errors) ==== class C extends A implements { - -!!! error TS1097: 'implements' list cannot be empty. ~ !!! error TS2304: Cannot find name 'A'. + +!!! error TS1097: 'implements' list cannot be empty. } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause5.errors.txt b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause5.errors.txt index 7ffab4742f3..e1ab30fe5f1 100644 --- a/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause5.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ExtendsOrImplementsClause5.errors.txt @@ -1,17 +1,17 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,18): error TS1009: Trailing comma not allowed. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,32): error TS1009: Trailing comma not allowed. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,17): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,18): error TS1009: Trailing comma not allowed. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,31): error TS2304: Cannot find name 'B'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts(1,32): error TS1009: Trailing comma not allowed. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ExtendsOrImplementsClauses/parserErrorRecovery_ExtendsOrImplementsClause5.ts (4 errors) ==== class C extends A, implements B, { - ~ -!!! error TS1009: Trailing comma not allowed. - ~ -!!! error TS1009: Trailing comma not allowed. ~ !!! error TS2304: Cannot find name 'A'. + ~ +!!! error TS1009: Trailing comma not allowed. ~ !!! error TS2304: Cannot find name 'B'. + ~ +!!! error TS1009: Trailing comma not allowed. } \ No newline at end of file diff --git a/tests/baselines/reference/parserInterfaceDeclaration1.errors.txt b/tests/baselines/reference/parserInterfaceDeclaration1.errors.txt index 8c8f317b11a..a85b21e6db6 100644 --- a/tests/baselines/reference/parserInterfaceDeclaration1.errors.txt +++ b/tests/baselines/reference/parserInterfaceDeclaration1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration1.ts(1,23): error TS1172: 'extends' clause already seen. tests/cases/conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration1.ts(1,21): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration1.ts(1,23): error TS1172: 'extends' clause already seen. ==== tests/cases/conformance/parser/ecmascript5/InterfaceDeclarations/parserInterfaceDeclaration1.ts (2 errors) ==== interface I extends A extends B { - ~~~~~~~ -!!! error TS1172: 'extends' clause already seen. ~ !!! error TS2304: Cannot find name 'A'. + ~~~~~~~ +!!! error TS1172: 'extends' clause already seen. } \ No newline at end of file