Disallow computed properties referencing type parameters from containing type

This commit is contained in:
Jason Freeman
2015-01-19 18:44:15 -08:00
parent b5349a5038
commit 89f36bb9c5
14 changed files with 193 additions and 0 deletions

View File

@@ -335,6 +335,16 @@ module ts {
break loop;
}
break;
case SyntaxKind.ComputedPropertyName:
var grandparent = location.parent.parent;
if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
// A reference to this grandparent's type parameters would be an error
if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) {
error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_contained_type);
return undefined;
}
}
break;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.Constructor:

View File

@@ -302,6 +302,7 @@ module ts {
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." },
super_cannot_be_referenced_in_a_computed_property_name: { code: 2466, category: DiagnosticCategory.Error, key: "'super' cannot be referenced in a computed property name." },
A_computed_property_name_cannot_reference_a_type_parameter_from_its_contained_type: { code: 2466, category: DiagnosticCategory.Error, key: "A computed property name cannot reference a type parameter from its contained type." },
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

@@ -1302,6 +1302,10 @@
"category": "Error",
"code": 2466
},
"A computed property name cannot reference a type parameter from its contained type.": {
"category": "Error",
"code": 2466
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@@ -0,0 +1,13 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts(6,10): error TS2466: A computed property name cannot reference a type parameter from its contained type.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts (1 errors) ====
function foo<T>() { return '' }
class C<T> {
bar() {
return 0;
}
[foo<T>()]() { }
~
!!! error TS2466: A computed property name cannot reference a type parameter from its contained type.
}

View File

@@ -0,0 +1,23 @@
//// [computedPropertyNames32.ts]
function foo<T>() { return '' }
class C<T> {
bar() {
return 0;
}
[foo<T>()]() { }
}
//// [computedPropertyNames32.js]
function foo() {
return '';
}
var C = (function () {
function C() {
}
C.prototype.bar = function () {
return 0;
};
C.prototype[foo()] = function () {
};
return C;
})();

View File

@@ -0,0 +1,27 @@
//// [computedPropertyNames33.ts]
function foo<T>() { return '' }
class C<T> {
bar() {
var obj = {
[foo<T>()]() { }
};
return 0;
}
}
//// [computedPropertyNames33.js]
function foo() {
return '';
}
var C = (function () {
function C() {
}
C.prototype.bar = function () {
var obj = {
[foo()]() {
}
};
return 0;
};
return C;
})();

View File

@@ -0,0 +1,25 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts ===
function foo<T>() { return '' }
>foo : <T>() => string
>T : T
class C<T> {
>C : C<T>
>T : T
bar() {
>bar : () => number
var obj = {
>obj : {}
>{ [foo<T>()]() { } } : {}
[foo<T>()]() { }
>foo<T>() : string
>foo : <T>() => string
>T : T
};
return 0;
}
}

View File

@@ -0,0 +1,15 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts(5,18): error TS2302: Static members cannot reference class type parameters.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts (1 errors) ====
function foo<T>() { return '' }
class C<T> {
static bar() {
var obj = {
[foo<T>()]() { }
~
!!! error TS2302: Static members cannot reference class type parameters.
};
return 0;
}
}

View File

@@ -0,0 +1,27 @@
//// [computedPropertyNames34.ts]
function foo<T>() { return '' }
class C<T> {
static bar() {
var obj = {
[foo<T>()]() { }
};
return 0;
}
}
//// [computedPropertyNames34.js]
function foo() {
return '';
}
var C = (function () {
function C() {
}
C.bar = function () {
var obj = {
[foo()]() {
}
};
return 0;
};
return C;
})();

View File

@@ -0,0 +1,14 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts(4,5): error TS1169: Computed property names are not allowed in interfaces.
tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts(4,10): error TS2466: A computed property name cannot reference a type parameter from its contained type.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts (2 errors) ====
function foo<T>() { return '' }
interface I<T> {
bar(): string;
[foo<T>()](): void;
~~~~~~~~~~
!!! error TS1169: Computed property names are not allowed in interfaces.
~
!!! error TS2466: A computed property name cannot reference a type parameter from its contained type.
}

View File

@@ -0,0 +1,8 @@
// @target: es6
function foo<T>() { return '' }
class C<T> {
bar() {
return 0;
}
[foo<T>()]() { }
}

View File

@@ -0,0 +1,10 @@
// @target: es6
function foo<T>() { return '' }
class C<T> {
bar() {
var obj = {
[foo<T>()]() { }
};
return 0;
}
}

View File

@@ -0,0 +1,10 @@
// @target: es6
function foo<T>() { return '' }
class C<T> {
static bar() {
var obj = {
[foo<T>()]() { }
};
return 0;
}
}

View File

@@ -0,0 +1,6 @@
// @target: es6
function foo<T>() { return '' }
interface I<T> {
bar(): string;
[foo<T>()](): void;
}