Report property errors in the checker instead of the parser

This commit is contained in:
Nathan Yee 2015-11-27 18:11:28 -08:00
parent 068d10c6bb
commit 6c755c90db
13 changed files with 100 additions and 47 deletions

View File

@ -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 = <NodeArray<PropertySignature>>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 = <TypeLiteralNode>node.type;
if (typeLiteralNode.members) {
for (const element of typeLiteralNode.members) {
const propertySignature = <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 ;

View File

@ -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",

View File

@ -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);

View File

@ -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)

View File

@ -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.
}

View File

@ -0,0 +1,7 @@
//// [errorOnInitializerInInterfaceProperty.ts]
interface Foo {
bar: number = 5;
}
//// [errorOnInitializerInInterfaceProperty.js]

View File

@ -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.
};

View File

@ -1,12 +0,0 @@
//// [errorOnInitializerInObjectType.ts]
interface Foo {
bar: number = 5;
}
var Foo: {
bar: number = 5;
};
//// [errorOnInitializerInObjectType.js]
var Foo;

View File

@ -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.
};

View File

@ -0,0 +1,13 @@
//// [errorOnInitializerInObjectTypeLiteralProperty.ts]
var Foo: {
bar: number = 5;
};
let Bar: {
bar: number = 5;
};
//// [errorOnInitializerInObjectTypeLiteralProperty.js]
var Foo;
var Bar;

View File

@ -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.

View File

@ -0,0 +1,3 @@
interface Foo {
bar: number = 5;
}

View File

@ -1,7 +1,7 @@
interface Foo {
bar: number = 5;
}
var Foo: {
bar: number = 5;
};
var Foo: {
bar: number = 5;
};
let Bar: {
bar: number = 5;
};