Skip to content

Commit 39952b1

Browse files
committed
Syntactically allow computed properties everywhere if the name looks like a built in Symbol
1 parent b30d8f3 commit 39952b1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+357
-12
lines changed

src/compiler/checker.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -7487,7 +7487,7 @@ module ts {
74877487

74887488
function checkPropertyDeclaration(node: PropertyDeclaration) {
74897489
// Grammar checking
7490-
checkGrammarModifiers(node) || checkGrammarProperty(node);
7490+
checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
74917491

74927492
checkVariableLikeDeclaration(node);
74937493
}
@@ -10771,8 +10771,8 @@ module ts {
1077110771
}
1077210772
}
1077310773

10774-
function checkGrammarForDisallowedComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
10775-
if (node.kind === SyntaxKind.ComputedPropertyName) {
10774+
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
10775+
if (node.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically((<ComputedPropertyName>node).expression)) {
1077610776
return grammarErrorOnNode(node, message);
1077710777
}
1077810778
}
@@ -10803,17 +10803,17 @@ module ts {
1080310803
// and accessors are not allowed in ambient contexts in general,
1080410804
// so this error only really matters for methods.
1080510805
if (isInAmbientContext(node)) {
10806-
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_Symbol);
10806+
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_Symbol);
1080710807
}
1080810808
else if (!node.body) {
10809-
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_Symbol);
10809+
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_Symbol);
1081010810
}
1081110811
}
1081210812
else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) {
10813-
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_Symbol);
10813+
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_Symbol);
1081410814
}
1081510815
else if (node.parent.kind === SyntaxKind.TypeLiteral) {
10816-
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_Symbol);
10816+
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_Symbol);
1081710817
}
1081810818
}
1081910819

@@ -11084,17 +11084,17 @@ module ts {
1108411084
function checkGrammarProperty(node: PropertyDeclaration) {
1108511085
if (node.parent.kind === SyntaxKind.ClassDeclaration) {
1108611086
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) ||
11087-
checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_Symbol)) {
11087+
checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_Symbol)) {
1108811088
return true;
1108911089
}
1109011090
}
1109111091
else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) {
11092-
if (checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_Symbol)) {
11092+
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_Symbol)) {
1109311093
return true;
1109411094
}
1109511095
}
1109611096
else if (node.parent.kind === SyntaxKind.TypeLiteral) {
11097-
if (checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_Symbol)) {
11097+
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_Symbol)) {
1109811098
return true;
1109911099
}
1110011100
}

src/compiler/utilities.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -835,11 +835,21 @@ module ts {
835835
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
836836
}
837837

838+
export function isWellKnownSymbolSyntactically(node: Node): boolean {
839+
return node.kind === SyntaxKind.PropertyAccessExpression && isESSymbolIdentifier((<PropertyAccessExpression>node).expression);
840+
}
841+
838842
export function isESSymbolTypeNode(node: Node): boolean {
839843
return node.kind === SyntaxKind.TypeReference &&
840844
(<TypeReferenceNode>node).typeArguments === undefined &&
841-
(<TypeReferenceNode>node).typeName.kind === SyntaxKind.Identifier &&
842-
(<Identifier>(<TypeReferenceNode>node).typeName).text === "Symbol";
845+
isESSymbolIdentifier((<TypeReferenceNode>node).typeName);
846+
}
847+
848+
/**
849+
* Includes the word "Symbol" with unicode escapes
850+
*/
851+
export function isESSymbolIdentifier(node: Node): boolean {
852+
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
843853
}
844854

845855
export function isModifier(token: SyntaxKind): boolean {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty1.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty1.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty1.ts (2 errors) ====
6+
interface I {
7+
[Symbol.iterator]: string;
8+
~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty2.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty2.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty2.ts (2 errors) ====
6+
interface I {
7+
[Symbol.unscopables](): string;
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty3.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty3.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty3.ts (2 errors) ====
6+
declare class C {
7+
[Symbol.unscopables](): string;
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty4.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty4.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty4.ts (2 errors) ====
6+
declare class C {
7+
[Symbol.isRegExp]: string;
8+
~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty5.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty5.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty5.ts (2 errors) ====
6+
class C {
7+
[Symbol.isRegExp]: string;
8+
~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty6.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty6.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty6.ts (2 errors) ====
6+
class C {
7+
[Symbol.toStringTag]: string = "";
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty7.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty7.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty7.ts (2 errors) ====
6+
class C {
7+
[Symbol.toStringTag](): void { }
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty8.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty8.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty8.ts (2 errors) ====
6+
var x: {
7+
[Symbol.toPrimitive](): string
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty9.ts(2,5): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty9.ts(2,6): error TS2304: Cannot find name 'Symbol'.
3+
4+
5+
==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolProperty9.ts (2 errors) ====
6+
var x: {
7+
[Symbol.toPrimitive]: string
8+
~~~~~~~~~~~~~~~~~~~~
9+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~~
11+
!!! error TS2304: Cannot find name 'Symbol'.
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty1.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty1.ts (1 errors) ====
5+
interface I {
6+
[Symbol.iterator]: string;
7+
~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [parserSymbolProperty1.ts]
2+
interface I {
3+
[Symbol.iterator]: string;
4+
}
5+
6+
//// [parserSymbolProperty1.js]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty2.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty2.ts (1 errors) ====
5+
interface I {
6+
[Symbol.unscopables](): string;
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [parserSymbolProperty2.ts]
2+
interface I {
3+
[Symbol.unscopables](): string;
4+
}
5+
6+
//// [parserSymbolProperty2.js]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty3.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty3.ts (1 errors) ====
5+
declare class C {
6+
[Symbol.unscopables](): string;
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [parserSymbolProperty3.ts]
2+
declare class C {
3+
[Symbol.unscopables](): string;
4+
}
5+
6+
//// [parserSymbolProperty3.js]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty4.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty4.ts (1 errors) ====
5+
declare class C {
6+
[Symbol.isRegExp]: string;
7+
~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [parserSymbolProperty4.ts]
2+
declare class C {
3+
[Symbol.isRegExp]: string;
4+
}
5+
6+
//// [parserSymbolProperty4.js]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty5.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty5.ts (1 errors) ====
5+
class C {
6+
[Symbol.isRegExp]: string;
7+
~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [parserSymbolProperty5.ts]
2+
class C {
3+
[Symbol.isRegExp]: string;
4+
}
5+
6+
//// [parserSymbolProperty5.js]
7+
var C = (function () {
8+
function C() {
9+
}
10+
return C;
11+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty6.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty6.ts (1 errors) ====
5+
class C {
6+
[Symbol.toStringTag]: string = "";
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//// [parserSymbolProperty6.ts]
2+
class C {
3+
[Symbol.toStringTag]: string = "";
4+
}
5+
6+
//// [parserSymbolProperty6.js]
7+
var C = (function () {
8+
function C() {
9+
this[Symbol.toStringTag] = "";
10+
}
11+
return C;
12+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty7.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty7.ts (1 errors) ====
5+
class C {
6+
[Symbol.toStringTag](): void { }
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [parserSymbolProperty7.ts]
2+
class C {
3+
[Symbol.toStringTag](): void { }
4+
}
5+
6+
//// [parserSymbolProperty7.js]
7+
var C = (function () {
8+
function C() {
9+
}
10+
C.prototype[Symbol.toStringTag] = function () {
11+
};
12+
return C;
13+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty8.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty8.ts (1 errors) ====
5+
var x: {
6+
[Symbol.toPrimitive](): string
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [parserSymbolProperty8.ts]
2+
var x: {
3+
[Symbol.toPrimitive](): string
4+
}
5+
6+
//// [parserSymbolProperty8.js]
7+
var x;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty9.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolProperty9.ts (1 errors) ====
5+
var x: {
6+
[Symbol.toPrimitive]: string
7+
~~~~~~~~~~~~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [parserSymbolProperty9.ts]
2+
var x: {
3+
[Symbol.toPrimitive]: string
4+
}
5+
6+
//// [parserSymbolProperty9.js]
7+
var x;

0 commit comments

Comments
 (0)