diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd6b1d818182d..60d483c577de5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -201,6 +201,13 @@ namespace ts { } }; + const reservedStaticPropertyNames: { [key: string]: string } = { + length: "length", + arguments: "arguments", + caller: "caller", + name: "name" + }; + const JsxNames = { JSX: "JSX", IntrinsicElements: "IntrinsicElements", @@ -15082,6 +15089,9 @@ namespace ts { break; case SyntaxKind.StaticKeyword: + if (node.kind === SyntaxKind.Identifier && reservedStaticPropertyNames[node.symbol.name]) { + return grammarErrorOnNode(node, Diagnostics._0_cannot_be_used_as_a_static_member_identifier, node.symbol.name); + } if (flags & NodeFlags.Static) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static"); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9ea9514b4af73..9bd20997bb5ee 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1724,6 +1724,10 @@ "category": "Error", "code": 2657 }, + "'{0}' cannot be used as a static member identifier.": { + "category":"Error", + "code": 2658 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/tests/baselines/reference/reservedNameWithStaticProperty.js b/tests/baselines/reference/reservedNameWithStaticProperty.js new file mode 100644 index 0000000000000..e1c1b9a7640ab --- /dev/null +++ b/tests/baselines/reference/reservedNameWithStaticProperty.js @@ -0,0 +1,42 @@ +//// [reservedNameWithStaticProperty.ts] +class Length { + static length: string = "pizza"; +} + +class Caller { + static caller: string = "potatos"; +} + +class Arguments { + static arguments: string = "tomatoes" +} + +class Name { + static name: string = "name" +} + +//// [reservedNameWithStaticProperty.js] +var Length = (function () { + function Length() { + } + Length.length = "pizza"; + return Length; +})(); +var Caller = (function () { + function Caller() { + } + Caller.caller = "potatos"; + return Caller; +})(); +var Arguments = (function () { + function Arguments() { + } + Arguments.arguments = "tomatoes"; + return Arguments; +})(); +var Name = (function () { + function Name() { + } + Name.name = "name"; + return Name; +})(); diff --git a/tests/baselines/reference/reservedNameWithStaticProperty.symbols b/tests/baselines/reference/reservedNameWithStaticProperty.symbols new file mode 100644 index 0000000000000..123359a178ed4 --- /dev/null +++ b/tests/baselines/reference/reservedNameWithStaticProperty.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/reservedNameWithStaticProperty.ts === +class Length { +>Length : Symbol(Length, Decl(reservedNameWithStaticProperty.ts, 0, 0)) + + static length: string = "pizza"; +>length : Symbol(Length.length, Decl(reservedNameWithStaticProperty.ts, 0, 14)) +} + +class Caller { +>Caller : Symbol(Caller, Decl(reservedNameWithStaticProperty.ts, 2, 1)) + + static caller: string = "potatos"; +>caller : Symbol(Caller.caller, Decl(reservedNameWithStaticProperty.ts, 4, 14)) +} + +class Arguments { +>Arguments : Symbol(Arguments, Decl(reservedNameWithStaticProperty.ts, 6, 1)) + + static arguments: string = "tomatoes" +>arguments : Symbol(Arguments.arguments, Decl(reservedNameWithStaticProperty.ts, 8, 17)) +} + +class Name { +>Name : Symbol(Name, Decl(reservedNameWithStaticProperty.ts, 10, 1)) + + static name: string = "name" +>name : Symbol(Name.name, Decl(reservedNameWithStaticProperty.ts, 12, 12)) +} diff --git a/tests/baselines/reference/reservedNameWithStaticProperty.types b/tests/baselines/reference/reservedNameWithStaticProperty.types new file mode 100644 index 0000000000000..a812d55bf5f86 --- /dev/null +++ b/tests/baselines/reference/reservedNameWithStaticProperty.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/reservedNameWithStaticProperty.ts === +class Length { +>Length : Length + + static length: string = "pizza"; +>length : string +>"pizza" : string +} + +class Caller { +>Caller : Caller + + static caller: string = "potatos"; +>caller : string +>"potatos" : string +} + +class Arguments { +>Arguments : Arguments + + static arguments: string = "tomatoes" +>arguments : string +>"tomatoes" : string +} + +class Name { +>Name : Name + + static name: string = "name" +>name : string +>"name" : string +} diff --git a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt index 5962654080621..708539bb70a4d 100644 --- a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt +++ b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt @@ -1,43 +1,43 @@ tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(12,1): error TS2322: Type 'C' is not assignable to type 'A'. - Property 'name' is missing in type 'C'. + Property 'beep' is missing in type 'C'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(13,1): error TS2322: Type 'typeof B' is not assignable to type 'A'. - Property 'name' is missing in type 'typeof B'. + Property 'beep' is missing in type 'typeof B'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(16,5): error TS2322: Type 'C' is not assignable to type 'B'. - Property 'name' is missing in type 'C'. + Property 'beep' is missing in type 'C'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(17,1): error TS2322: Type 'typeof B' is not assignable to type 'B'. - Property 'name' is missing in type 'typeof B'. + Property 'beep' is missing in type 'typeof B'. ==== tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts (4 errors) ==== interface A { - name(); + beep(); } class B { - public name() { } + public beep() { } } class C { - public static name() { } + public static beep() { } } var a: A = new B(); - a = new C(); // error name is missing + a = new C(); // error beep is missing ~ !!! error TS2322: Type 'C' is not assignable to type 'A'. -!!! error TS2322: Property 'name' is missing in type 'C'. - a = B; // error name is missing +!!! error TS2322: Property 'beep' is missing in type 'C'. + a = B; // error beep is missing ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'A'. -!!! error TS2322: Property 'name' is missing in type 'typeof B'. +!!! error TS2322: Property 'beep' is missing in type 'typeof B'. a = C; var b: B = new C(); // error name is missing ~ !!! error TS2322: Type 'C' is not assignable to type 'B'. -!!! error TS2322: Property 'name' is missing in type 'C'. - b = B; // error name is missing +!!! error TS2322: Property 'beep' is missing in type 'C'. + b = B; // error beep is missing ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'B'. -!!! error TS2322: Property 'name' is missing in type 'typeof B'. +!!! error TS2322: Property 'beep' is missing in type 'typeof B'. b = C; b = a; diff --git a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js index 7b24a29b326a3..8e032dc6c357d 100644 --- a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js +++ b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js @@ -1,21 +1,21 @@ //// [staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts] interface A { - name(); + beep(); } class B { - public name() { } + public beep() { } } class C { - public static name() { } + public static beep() { } } var a: A = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error beep is missing +a = B; // error beep is missing a = C; var b: B = new C(); // error name is missing -b = B; // error name is missing +b = B; // error beep is missing b = C; b = a; @@ -29,21 +29,21 @@ c = a; var B = (function () { function B() { } - B.prototype.name = function () { }; + B.prototype.beep = function () { }; return B; })(); var C = (function () { function C() { } - C.name = function () { }; + C.beep = function () { }; return C; })(); var a = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error beep is missing +a = B; // error beep is missing a = C; var b = new C(); // error name is missing -b = B; // error name is missing +b = B; // error beep is missing b = C; b = a; var c = new B(); diff --git a/tests/cases/compiler/reservedNameWithStaticProperty.ts b/tests/cases/compiler/reservedNameWithStaticProperty.ts new file mode 100644 index 0000000000000..0cba1d610f242 --- /dev/null +++ b/tests/cases/compiler/reservedNameWithStaticProperty.ts @@ -0,0 +1,15 @@ +class Length { + static length: string = "pizza"; +} + +class Caller { + static caller: string = "potatos"; +} + +class Arguments { + static arguments: string = "tomatoes" +} + +class Name { + static name: string = "name" +} \ No newline at end of file diff --git a/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts b/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts index c8ebc3121043a..c69db04efd462 100644 --- a/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts +++ b/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts @@ -1,20 +1,20 @@ interface A { - name(); + beep(); } class B { - public name() { } + public beep() { } } class C { - public static name() { } + public static beep() { } } var a: A = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error beep is missing +a = B; // error beep is missing a = C; var b: B = new C(); // error name is missing -b = B; // error name is missing +b = B; // error beep is missing b = C; b = a;