Disallow this in computed properties in classes

This commit is contained in:
Jason Freeman
2015-01-16 19:15:24 -08:00
parent f943f6c486
commit 4cc2722700
23 changed files with 240 additions and 0 deletions

View File

@@ -4853,6 +4853,9 @@ module ts {
// do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
}
break;
case SyntaxKind.ComputedPropertyName:
error(node, Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
break;
}
if (needToCaptureLexicalThis) {

View File

@@ -300,6 +300,7 @@ module ts {
A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: DiagnosticCategory.Error, key: "A rest element must be last in an array destructuring pattern" },
A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: { code: 2463, category: DiagnosticCategory.Error, key: "A binding pattern parameter cannot be optional in an implementation signature." },
A_computed_property_name_must_be_of_type_string_number_or_any: { code: 2464, category: DiagnosticCategory.Error, key: "A computed property name must be of type 'string', 'number', or 'any'." },
this_cannot_be_referenced_in_a_computed_property_name: { code: 2465, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in a computed property name." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },

View File

@@ -1294,6 +1294,10 @@
"category": "Error",
"code": 2464
},
"'this' cannot be referenced in a computed property name.": {
"category": "Error",
"code": 2465
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@@ -399,6 +399,14 @@ module ts {
return undefined;
}
switch (node.kind) {
case SyntaxKind.ComputedPropertyName:
// If the grandparent node is an object literal (as opposed to a class),
// then the computed property is not a 'this' container.
// A computed property name in a class needs to be a this container
// so that we can error on it.
if (node.parent.parent.kind !== SyntaxKind.ClassDeclaration) {
continue;
}
case SyntaxKind.ArrowFunction:
if (!includeArrowFunctions) {
continue;

View File

@@ -4191,6 +4191,8 @@ module ts {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
break;
// Computed properties in classes are not handled here because references to this are illegal,
// so there is no point finding references to them.
default:
return undefined;
}

View File

@@ -0,0 +1,13 @@
//// [computedPropertyNames18.ts]
function foo() {
var obj = {
[this.bar]: 0
}
}
//// [computedPropertyNames18.js]
function foo() {
var obj = {
[this.bar]: 0
};
}

View File

@@ -0,0 +1,14 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames18.ts ===
function foo() {
>foo : () => void
var obj = {
>obj : {}
>{ [this.bar]: 0 } : {}
[this.bar]: 0
>this.bar : any
>this : any
>bar : any
}
}

View File

@@ -0,0 +1,11 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames19.ts(3,10): error TS2331: 'this' cannot be referenced in a module body.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames19.ts (1 errors) ====
module M {
var obj = {
[this.bar]: 0
~~~~
!!! error TS2331: 'this' cannot be referenced in a module body.
}
}

View File

@@ -0,0 +1,14 @@
//// [computedPropertyNames19.ts]
module M {
var obj = {
[this.bar]: 0
}
}
//// [computedPropertyNames19.js]
var M;
(function (M) {
var obj = {
[this.bar]: 0
};
})(M || (M = {}));

View File

@@ -0,0 +1,9 @@
//// [computedPropertyNames20.ts]
var obj = {
[this.bar]: 0
}
//// [computedPropertyNames20.js]
var obj = {
[this.bar]: 0
};

View File

@@ -0,0 +1,10 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames20.ts ===
var obj = {
>obj : {}
>{ [this.bar]: 0} : {}
[this.bar]: 0
>this.bar : any
>this : any
>bar : any
}

View File

@@ -0,0 +1,12 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames21.ts(5,6): error TS2465: 'this' cannot be referenced in a computed property name.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames21.ts (1 errors) ====
class C {
bar() {
return 0;
}
[this.bar()]() { }
~~~~
!!! error TS2465: 'this' cannot be referenced in a computed property name.
}

View File

@@ -0,0 +1,19 @@
//// [computedPropertyNames21.ts]
class C {
bar() {
return 0;
}
[this.bar()]() { }
}
//// [computedPropertyNames21.js]
var C = (function () {
function C() {
}
C.prototype.bar = function () {
return 0;
};
C.prototype[this.bar()] = function () {
};
return C;
})();

View File

@@ -0,0 +1,23 @@
//// [computedPropertyNames22.ts]
class C {
bar() {
var obj = {
[this.bar()]() { }
};
return 0;
}
}
//// [computedPropertyNames22.js]
var C = (function () {
function C() {
}
C.prototype.bar = function () {
var obj = {
[this.bar()]() {
}
};
return 0;
};
return C;
})();

View File

@@ -0,0 +1,21 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames22.ts ===
class C {
>C : C
bar() {
>bar : () => number
var obj = {
>obj : {}
>{ [this.bar()]() { } } : {}
[this.bar()]() { }
>this.bar() : any
>this.bar : any
>this : any
>bar : any
};
return 0;
}
}

View File

@@ -0,0 +1,14 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames23.ts(6,12): error TS2465: 'this' cannot be referenced in a computed property name.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames23.ts (1 errors) ====
class C {
bar() {
return 0;
}
[
{ [this.bar()]: 1 }[0]
~~~~
!!! error TS2465: 'this' cannot be referenced in a computed property name.
]() { }
}

View File

@@ -0,0 +1,21 @@
//// [computedPropertyNames23.ts]
class C {
bar() {
return 0;
}
[
{ [this.bar()]: 1 }[0]
]() { }
}
//// [computedPropertyNames23.js]
var C = (function () {
function C() {
}
C.prototype.bar = function () {
return 0;
};
C.prototype[{ [this.bar()]: 1 }[0]] = function () {
};
return C;
})();

View File

@@ -0,0 +1,6 @@
// @target: es6
function foo() {
var obj = {
[this.bar]: 0
}
}

View File

@@ -0,0 +1,6 @@
// @target: es6
module M {
var obj = {
[this.bar]: 0
}
}

View File

@@ -0,0 +1,4 @@
// @target: es6
var obj = {
[this.bar]: 0
}

View File

@@ -0,0 +1,7 @@
// @target: es6
class C {
bar() {
return 0;
}
[this.bar()]() { }
}

View File

@@ -0,0 +1,9 @@
// @target: es6
class C {
bar() {
var obj = {
[this.bar()]() { }
};
return 0;
}
}

View File

@@ -0,0 +1,9 @@
// @target: es6
class C {
bar() {
return 0;
}
[
{ [this.bar()]: 1 }[0]
]() { }
}