From 89f36bb9c53b7c9511736c179aeda072179ff943 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Mon, 19 Jan 2015 18:44:15 -0800 Subject: [PATCH] Disallow computed properties referencing type parameters from containing type --- src/compiler/checker.ts | 10 +++++++ .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 +++ .../computedPropertyNames32.errors.txt | 13 +++++++++ .../reference/computedPropertyNames32.js | 23 ++++++++++++++++ .../reference/computedPropertyNames33.js | 27 +++++++++++++++++++ .../reference/computedPropertyNames33.types | 25 +++++++++++++++++ .../computedPropertyNames34.errors.txt | 15 +++++++++++ .../reference/computedPropertyNames34.js | 27 +++++++++++++++++++ .../computedPropertyNames35.errors.txt | 14 ++++++++++ .../computedPropertyNames32.ts | 8 ++++++ .../computedPropertyNames33.ts | 10 +++++++ .../computedPropertyNames34.ts | 10 +++++++ .../computedPropertyNames35.ts | 6 +++++ 14 files changed, 193 insertions(+) create mode 100644 tests/baselines/reference/computedPropertyNames32.errors.txt create mode 100644 tests/baselines/reference/computedPropertyNames32.js create mode 100644 tests/baselines/reference/computedPropertyNames33.js create mode 100644 tests/baselines/reference/computedPropertyNames33.types create mode 100644 tests/baselines/reference/computedPropertyNames34.errors.txt create mode 100644 tests/baselines/reference/computedPropertyNames34.js create mode 100644 tests/baselines/reference/computedPropertyNames35.errors.txt create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1fc3227e5ec..42612ed4cdc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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: diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 0a8c3a7edfe..fc47f0257a7 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -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}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2d1b4e4daf0..6b00591556f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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", diff --git a/tests/baselines/reference/computedPropertyNames32.errors.txt b/tests/baselines/reference/computedPropertyNames32.errors.txt new file mode 100644 index 00000000000..8a7b0995153 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames32.errors.txt @@ -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() { return '' } + class C { + bar() { + return 0; + } + [foo()]() { } + ~ +!!! error TS2466: A computed property name cannot reference a type parameter from its contained type. + } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames32.js b/tests/baselines/reference/computedPropertyNames32.js new file mode 100644 index 00000000000..d3e98681369 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames32.js @@ -0,0 +1,23 @@ +//// [computedPropertyNames32.ts] +function foo() { return '' } +class C { + bar() { + return 0; + } + [foo()]() { } +} + +//// [computedPropertyNames32.js] +function foo() { + return ''; +} +var C = (function () { + function C() { + } + C.prototype.bar = function () { + return 0; + }; + C.prototype[foo()] = function () { + }; + return C; +})(); diff --git a/tests/baselines/reference/computedPropertyNames33.js b/tests/baselines/reference/computedPropertyNames33.js new file mode 100644 index 00000000000..554ec315897 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames33.js @@ -0,0 +1,27 @@ +//// [computedPropertyNames33.ts] +function foo() { return '' } +class C { + bar() { + var obj = { + [foo()]() { } + }; + return 0; + } +} + +//// [computedPropertyNames33.js] +function foo() { + return ''; +} +var C = (function () { + function C() { + } + C.prototype.bar = function () { + var obj = { + [foo()]() { + } + }; + return 0; + }; + return C; +})(); diff --git a/tests/baselines/reference/computedPropertyNames33.types b/tests/baselines/reference/computedPropertyNames33.types new file mode 100644 index 00000000000..8cbe8e93ef2 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames33.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts === +function foo() { return '' } +>foo : () => string +>T : T + +class C { +>C : C +>T : T + + bar() { +>bar : () => number + + var obj = { +>obj : {} +>{ [foo()]() { } } : {} + + [foo()]() { } +>foo() : string +>foo : () => string +>T : T + + }; + return 0; + } +} diff --git a/tests/baselines/reference/computedPropertyNames34.errors.txt b/tests/baselines/reference/computedPropertyNames34.errors.txt new file mode 100644 index 00000000000..c6d4a9aa4eb --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames34.errors.txt @@ -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() { return '' } + class C { + static bar() { + var obj = { + [foo()]() { } + ~ +!!! error TS2302: Static members cannot reference class type parameters. + }; + return 0; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames34.js b/tests/baselines/reference/computedPropertyNames34.js new file mode 100644 index 00000000000..f1d774139b1 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames34.js @@ -0,0 +1,27 @@ +//// [computedPropertyNames34.ts] +function foo() { return '' } +class C { + static bar() { + var obj = { + [foo()]() { } + }; + return 0; + } +} + +//// [computedPropertyNames34.js] +function foo() { + return ''; +} +var C = (function () { + function C() { + } + C.bar = function () { + var obj = { + [foo()]() { + } + }; + return 0; + }; + return C; +})(); diff --git a/tests/baselines/reference/computedPropertyNames35.errors.txt b/tests/baselines/reference/computedPropertyNames35.errors.txt new file mode 100644 index 00000000000..665831d6382 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNames35.errors.txt @@ -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() { return '' } + interface I { + bar(): string; + [foo()](): 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. + } \ No newline at end of file diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts new file mode 100644 index 00000000000..bf888a0c44b --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNames32.ts @@ -0,0 +1,8 @@ +// @target: es6 +function foo() { return '' } +class C { + bar() { + return 0; + } + [foo()]() { } +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts new file mode 100644 index 00000000000..2a62d003a2e --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNames33.ts @@ -0,0 +1,10 @@ +// @target: es6 +function foo() { return '' } +class C { + bar() { + var obj = { + [foo()]() { } + }; + return 0; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts new file mode 100644 index 00000000000..2a56735701c --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNames34.ts @@ -0,0 +1,10 @@ +// @target: es6 +function foo() { return '' } +class C { + static bar() { + var obj = { + [foo()]() { } + }; + return 0; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts new file mode 100644 index 00000000000..f2e2929bf75 --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNames35.ts @@ -0,0 +1,6 @@ +// @target: es6 +function foo() { return '' } +interface I { + bar(): string; + [foo()](): void; +} \ No newline at end of file