From 6c755c90db635d698449ad104a274b6eabaabd90 Mon Sep 17 00:00:00 2001 From: Nathan Yee Date: Fri, 27 Nov 2015 18:11:28 -0800 Subject: [PATCH] Report property errors in the checker instead of the parser --- src/compiler/checker.ts | 30 ++++++++++++++++--- src/compiler/diagnosticMessages.json | 6 +++- src/compiler/parser.ts | 7 ++--- src/compiler/types.ts | 1 + ...nInitializerInInterfaceProperty.errors.txt | 10 +++++++ .../errorOnInitializerInInterfaceProperty.js | 7 +++++ .../errorOnInitializerInObjectType.errors.txt | 17 ----------- .../errorOnInitializerInObjectType.js | 12 -------- ...izerInObjectTypeLiteralProperty.errors.txt | 17 +++++++++++ ...nInitializerInObjectTypeLiteralProperty.js | 13 ++++++++ .../objectTypeLiteralSyntax2.errors.txt | 10 +++++-- .../errorOnInitializerInInterfaceProperty.ts | 3 ++ ...InitializerInObjectTypeLiteralProperty.ts} | 14 ++++----- 13 files changed, 100 insertions(+), 47 deletions(-) create mode 100644 tests/baselines/reference/errorOnInitializerInInterfaceProperty.errors.txt create mode 100644 tests/baselines/reference/errorOnInitializerInInterfaceProperty.js delete mode 100644 tests/baselines/reference/errorOnInitializerInObjectType.errors.txt delete mode 100644 tests/baselines/reference/errorOnInitializerInObjectType.js create mode 100644 tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.errors.txt create mode 100644 tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.js create mode 100644 tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts rename tests/cases/compiler/{errorOnInitializerInObjectType.ts => errorOnInitializerInObjectTypeLiteralProperty.ts} (73%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1b6b31f9586..0b889a42045 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -532,7 +532,7 @@ namespace ts { } // Because of module/namespace merging, a module's exports are in scope, - // yet we never want to treat an export specifier as putting a member in scope. + // yet we never want to treat an export specifier as putting a member in scope. // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope. // Two things to note about this: // 1. We have to check this without calling getSymbol. The problem with calling getSymbol @@ -11398,7 +11398,7 @@ namespace ts { // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging - // here we'll report error only for the first case since for second we should already report error in binder + // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; error(errorNode, diagnostic); @@ -12065,8 +12065,8 @@ namespace ts { const symbol = getSymbolOfNode(node); const localSymbol = node.localSymbol || symbol; - // Since the javascript won't do semantic analysis like typescript, - // if the javascript file comes before the typescript file and both contain same name functions, + // Since the javascript won't do semantic analysis like typescript, + // if the javascript file comes before the typescript file and both contain same name functions, // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function. const firstDeclaration = forEach(localSymbol.declarations, // Get first non javascript function declaration @@ -15735,6 +15735,16 @@ namespace ts { } } + // Report an error if an interface property has an initializer + if (node.members) { + const members = >node.members; + for (const element of members) { + if (element.initializer) { + return grammarErrorOnFirstToken(element.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer); + } + } + } + return false; } @@ -16085,6 +16095,18 @@ namespace ts { } } + if (node.type) { + const typeLiteralNode = node.type; + if (typeLiteralNode.members) { + for (const element of typeLiteralNode.members) { + const propertySignature = element; + if (propertySignature.initializer) { + return grammarErrorOnNode(propertySignature.initializer, Diagnostics.An_object_type_literal_property_cannot_have_an_initializer); + } + } + } + } + const checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node)); // 1. LexicalDeclaration : LetOrConst BindingList ; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e5a5e832b4d..e3ae2a6706c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -783,10 +783,14 @@ "category": "Error", "code": 1245 }, - "An object type property cannot have an initializer.": { + "An interface property cannot have an initializer.": { "category": "Error", "code": 1246 }, + "An object type literal property cannot have an initializer.": { + "category": "Error", + "code": 1247 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4a7ed6a7756..2c68ea66bab 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2249,10 +2249,9 @@ namespace ts { property.type = parseTypeAnnotation(); // Although object type properties cannot not have initializers, we attempt to parse an initializer - // so we can report that an object type property cannot have an initializer. - if (token === SyntaxKind.EqualsToken && lookAhead(() => parseNonParameterInitializer()) !== undefined) { - parseErrorAtCurrentToken(Diagnostics.An_object_type_property_cannot_have_an_initializer); - } + // so we can report in the checker that an interface property or object type literal property cannot + // have an initializer. + property.initializer = parseNonParameterInitializer(); parseTypeMemberSemicolon(); return finishNode(property); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9edd7654b6b..58250c9dc5e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -586,6 +586,7 @@ namespace ts { name: PropertyName; // Declared property name questionToken?: Node; // Present on optional property type?: TypeNode; // Optional type annotation + initializer?: Expression; // Optional initializer } // @kind(SyntaxKind.PropertyDeclaration) diff --git a/tests/baselines/reference/errorOnInitializerInInterfaceProperty.errors.txt b/tests/baselines/reference/errorOnInitializerInInterfaceProperty.errors.txt new file mode 100644 index 00000000000..03e899e7c2d --- /dev/null +++ b/tests/baselines/reference/errorOnInitializerInInterfaceProperty.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts(2,19): error TS1246: An interface property cannot have an initializer. + + +==== tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts (1 errors) ==== + interface Foo { + bar: number = 5; + ~ +!!! error TS1246: An interface property cannot have an initializer. + } + \ No newline at end of file diff --git a/tests/baselines/reference/errorOnInitializerInInterfaceProperty.js b/tests/baselines/reference/errorOnInitializerInInterfaceProperty.js new file mode 100644 index 00000000000..c40a3cfb43d --- /dev/null +++ b/tests/baselines/reference/errorOnInitializerInInterfaceProperty.js @@ -0,0 +1,7 @@ +//// [errorOnInitializerInInterfaceProperty.ts] +interface Foo { + bar: number = 5; +} + + +//// [errorOnInitializerInInterfaceProperty.js] diff --git a/tests/baselines/reference/errorOnInitializerInObjectType.errors.txt b/tests/baselines/reference/errorOnInitializerInObjectType.errors.txt deleted file mode 100644 index 70cefb0e914..00000000000 --- a/tests/baselines/reference/errorOnInitializerInObjectType.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -tests/cases/compiler/errorOnInitializerInObjectType.ts(2,17): error TS1246: An object type property cannot have an initializer. -tests/cases/compiler/errorOnInitializerInObjectType.ts(6,17): error TS1246: An object type property cannot have an initializer. - - -==== tests/cases/compiler/errorOnInitializerInObjectType.ts (2 errors) ==== - interface Foo { - bar: number = 5; - ~ -!!! error TS1246: An object type property cannot have an initializer. - } - - var Foo: { - bar: number = 5; - ~ -!!! error TS1246: An object type property cannot have an initializer. - }; - \ No newline at end of file diff --git a/tests/baselines/reference/errorOnInitializerInObjectType.js b/tests/baselines/reference/errorOnInitializerInObjectType.js deleted file mode 100644 index 59e813fc75c..00000000000 --- a/tests/baselines/reference/errorOnInitializerInObjectType.js +++ /dev/null @@ -1,12 +0,0 @@ -//// [errorOnInitializerInObjectType.ts] -interface Foo { - bar: number = 5; -} - -var Foo: { - bar: number = 5; -}; - - -//// [errorOnInitializerInObjectType.js] -var Foo; diff --git a/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.errors.txt b/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.errors.txt new file mode 100644 index 00000000000..d79cced45c7 --- /dev/null +++ b/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts(2,19): error TS1247: An object type literal property cannot have an initializer. +tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts(6,19): error TS1247: An object type literal property cannot have an initializer. + + +==== tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts (2 errors) ==== + var Foo: { + bar: number = 5; + ~ +!!! error TS1247: An object type literal property cannot have an initializer. + }; + + let Bar: { + bar: number = 5; + ~ +!!! error TS1247: An object type literal property cannot have an initializer. + }; + \ No newline at end of file diff --git a/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.js b/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.js new file mode 100644 index 00000000000..4dcc0b7dce6 --- /dev/null +++ b/tests/baselines/reference/errorOnInitializerInObjectTypeLiteralProperty.js @@ -0,0 +1,13 @@ +//// [errorOnInitializerInObjectTypeLiteralProperty.ts] +var Foo: { + bar: number = 5; +}; + +let Bar: { + bar: number = 5; +}; + + +//// [errorOnInitializerInObjectTypeLiteralProperty.js] +var Foo; +var Bar; diff --git a/tests/baselines/reference/objectTypeLiteralSyntax2.errors.txt b/tests/baselines/reference/objectTypeLiteralSyntax2.errors.txt index 00442f4f87d..e4f923def58 100644 --- a/tests/baselines/reference/objectTypeLiteralSyntax2.errors.txt +++ b/tests/baselines/reference/objectTypeLiteralSyntax2.errors.txt @@ -1,7 +1,9 @@ -tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS1005: ';' expected. +tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS1005: '=' expected. +tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS2304: Cannot find name 'bar'. +tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,25): error TS1005: ';' expected. -==== tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts (1 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts (3 errors) ==== var x: { foo: string, bar: string @@ -15,4 +17,8 @@ tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,2 var z: { foo: string bar: string } ~~~ +!!! error TS1005: '=' expected. + ~~~ +!!! error TS2304: Cannot find name 'bar'. + ~ !!! error TS1005: ';' expected. \ No newline at end of file diff --git a/tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts b/tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts new file mode 100644 index 00000000000..ac600103e72 --- /dev/null +++ b/tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts @@ -0,0 +1,3 @@ +interface Foo { + bar: number = 5; +} diff --git a/tests/cases/compiler/errorOnInitializerInObjectType.ts b/tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts similarity index 73% rename from tests/cases/compiler/errorOnInitializerInObjectType.ts rename to tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts index 8c536d1a712..a02f8b0f709 100644 --- a/tests/cases/compiler/errorOnInitializerInObjectType.ts +++ b/tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts @@ -1,7 +1,7 @@ -interface Foo { - bar: number = 5; -} - -var Foo: { - bar: number = 5; -}; +var Foo: { + bar: number = 5; +}; + +let Bar: { + bar: number = 5; +};