Skip to content

Commit 5596993

Browse files
committed
Merge branch 'master' into forOf
Conflicts: src/compiler/diagnosticInformationMap.generated.ts src/compiler/diagnosticMessages.json tests/baselines/reference/APISample_compile.js tests/baselines/reference/APISample_compile.types tests/baselines/reference/APISample_linter.js tests/baselines/reference/APISample_linter.types tests/baselines/reference/APISample_transform.js tests/baselines/reference/APISample_transform.types tests/baselines/reference/APISample_watcher.js tests/baselines/reference/APISample_watcher.types
2 parents 6c32a6a + aa13a97 commit 5596993

487 files changed

Lines changed: 7474 additions & 1294 deletions

File tree

Some content is hidden

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

src/compiler/binder.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,6 @@ module ts {
5151
}
5252
}
5353

54-
/**
55-
* A declaration has a dynamic name if both of the following are true:
56-
* 1. The declaration has a computed property name
57-
* 2. The computed name is *not* expressed as Symbol.<name>, where name
58-
* is a property of the Symbol constructor that denotes a built in
59-
* Symbol.
60-
*/
61-
export function hasDynamicName(declaration: Declaration): boolean {
62-
return declaration.name && declaration.name.kind === SyntaxKind.ComputedPropertyName;
63-
}
64-
6554
export function bindSourceFile(file: SourceFile): void {
6655
var start = new Date().getTime();
6756
bindSourceFileWorker(file);
@@ -98,13 +87,18 @@ module ts {
9887
if (symbolKind & SymbolFlags.Value && !symbol.valueDeclaration) symbol.valueDeclaration = node;
9988
}
10089

101-
// Should not be called on a declaration with a computed property name.
90+
// Should not be called on a declaration with a computed property name,
91+
// unless it is a well known Symbol.
10292
function getDeclarationName(node: Declaration): string {
10393
if (node.name) {
10494
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
10595
return '"' + (<LiteralExpression>node.name).text + '"';
10696
}
107-
Debug.assert(!hasDynamicName(node));
97+
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
98+
var nameExpression = (<ComputedPropertyName>node.name).expression;
99+
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
100+
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
101+
}
108102
return (<Identifier | LiteralExpression>node.name).text;
109103
}
110104
switch (node.kind) {

src/compiler/checker.ts

Lines changed: 244 additions & 68 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 24 additions & 20 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -483,27 +483,27 @@
483483
"category": "Error",
484484
"code": 1164
485485
},
486-
"Computed property names are not allowed in an ambient context.": {
486+
"A computed property name in an ambient context must directly refer to a built-in symbol.": {
487487
"category": "Error",
488488
"code": 1165
489489
},
490-
"Computed property names are not allowed in class property declarations.": {
490+
"A computed property name in a class property declaration must directly refer to a built-in symbol.": {
491491
"category": "Error",
492492
"code": 1166
493493
},
494494
"Computed property names are only available when targeting ECMAScript 6 and higher.": {
495495
"category": "Error",
496496
"code": 1167
497497
},
498-
"Computed property names are not allowed in method overloads.": {
498+
"A computed property name in a method overload must directly refer to a built-in symbol.": {
499499
"category": "Error",
500500
"code": 1168
501501
},
502-
"Computed property names are not allowed in interfaces.": {
502+
"A computed property name in an interface must directly refer to a built-in symbol.": {
503503
"category": "Error",
504504
"code": 1169
505505
},
506-
"Computed property names are not allowed in type literals.": {
506+
"A computed property name in a type literal must directly refer to a built-in symbol.": {
507507
"category": "Error",
508508
"code": 1170
509509
},
@@ -668,7 +668,7 @@
668668
"category": "Error",
669669
"code": 2318
670670
},
671-
"Named properties '{0}' of types '{1}' and '{2}' are not identical.": {
671+
"Named property '{0}' of types '{1}' and '{2}' are not identical.": {
672672
"category": "Error",
673673
"code": 2319
674674
},
@@ -756,7 +756,7 @@
756756
"category": "Error",
757757
"code": 2341
758758
},
759-
"An index expression argument must be of type 'string', 'number', or 'any'.": {
759+
"An index expression argument must be of type 'string', 'number', 'symbol, or 'any'.": {
760760
"category": "Error",
761761
"code": 2342
762762
},
@@ -820,7 +820,7 @@
820820
"category": "Error",
821821
"code": 2359
822822
},
823-
"The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.": {
823+
"The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.": {
824824
"category": "Error",
825825
"code": 2360
826826
},
@@ -1200,7 +1200,7 @@
12001200
"category": "Error",
12011201
"code": 2463
12021202
},
1203-
"A computed property name must be of type 'string', 'number', or 'any'.": {
1203+
"A computed property name must be of type 'string', 'number', 'symbol', or 'any'.": {
12041204
"category": "Error",
12051205
"code": 2464
12061206
},
@@ -1214,48 +1214,64 @@
12141214
},
12151215
"A computed property name cannot reference a type parameter from its containing type.": {
12161216
"category": "Error",
1217-
"code": 2466
1217+
"code": 2467
12181218
},
1219-
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
1219+
"Cannot find global value '{0}'.": {
12201220
"category": "Error",
12211221
"code": 2468
12221222
},
1223-
"Enum declarations must all be const or non-const.": {
1223+
"The '{0}' operator cannot be applied to type 'symbol'.": {
12241224
"category": "Error",
12251225
"code": 2469
12261226
},
1227-
"In 'const' enum declarations member initializer must be constant expression.": {
1227+
"'Symbol' reference does not refer to the global Symbol constructor object.": {
12281228
"category": "Error",
12291229
"code": 2470
12301230
},
1231-
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": {
1231+
"A computed property name of the form '{0}' must be of type 'symbol'.": {
12321232
"category": "Error",
12331233
"code": 2471
12341234
},
1235-
"A const enum member can only be accessed using a string literal.": {
1235+
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
12361236
"category": "Error",
12371237
"code": 2472
12381238
},
1239-
"'const' enum member initializer was evaluated to a non-finite value.": {
1239+
"Enum declarations must all be const or non-const.": {
12401240
"category": "Error",
12411241
"code": 2473
12421242
},
1243-
"'const' enum member initializer was evaluated to disallowed value 'NaN'.": {
1243+
"In 'const' enum declarations member initializer must be constant expression.": {
12441244
"category": "Error",
12451245
"code": 2474
12461246
},
1247-
"Property '{0}' does not exist on 'const' enum '{1}'.": {
1247+
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": {
12481248
"category": "Error",
12491249
"code": 2475
12501250
},
1251-
"'let' is not allowed to be used as a name in 'let' or 'const' declarations.": {
1251+
"A const enum member can only be accessed using a string literal.": {
12521252
"category": "Error",
12531253
"code": 2476
12541254
},
1255-
"Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": {
1255+
"'const' enum member initializer was evaluated to a non-finite value.": {
12561256
"category": "Error",
12571257
"code": 2477
12581258
},
1259+
"'const' enum member initializer was evaluated to disallowed value 'NaN'.": {
1260+
"category": "Error",
1261+
"code": 2478
1262+
},
1263+
"Property '{0}' does not exist on 'const' enum '{1}'.": {
1264+
"category": "Error",
1265+
"code": 2479
1266+
},
1267+
"'let' is not allowed to be used as a name in 'let' or 'const' declarations.": {
1268+
"category": "Error",
1269+
"code": 2480
1270+
},
1271+
"Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": {
1272+
"category": "Error",
1273+
"code": 2481
1274+
},
12591275
"'for...of' statements are only available when targeting ECMAScript 6 or higher.": {
12601276
"category": "Error",
12611277
"code": 2482

src/compiler/emitter.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ module ts {
275275
var firstAccessor: AccessorDeclaration;
276276
var getAccessor: AccessorDeclaration;
277277
var setAccessor: AccessorDeclaration;
278-
if (accessor.name.kind === SyntaxKind.ComputedPropertyName) {
278+
if (hasDynamicName(accessor)) {
279279
firstAccessor = accessor;
280280
if (accessor.kind === SyntaxKind.GetAccessor) {
281281
getAccessor = accessor;
@@ -289,19 +289,22 @@ module ts {
289289
}
290290
else {
291291
forEach(node.members,(member: Declaration) => {
292-
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor) &&
293-
(<Identifier>member.name).text === (<Identifier>accessor.name).text &&
294-
(member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
295-
if (!firstAccessor) {
296-
firstAccessor = <AccessorDeclaration>member;
297-
}
292+
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
293+
&& (member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
294+
var memberName = getPropertyNameForPropertyNameNode(member.name);
295+
var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
296+
if (memberName === accessorName) {
297+
if (!firstAccessor) {
298+
firstAccessor = <AccessorDeclaration>member;
299+
}
298300

299-
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
300-
getAccessor = <AccessorDeclaration>member;
301-
}
301+
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
302+
getAccessor = <AccessorDeclaration>member;
303+
}
302304

303-
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
304-
setAccessor = <AccessorDeclaration>member;
305+
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
306+
setAccessor = <AccessorDeclaration>member;
307+
}
305308
}
306309
}
307310
});
@@ -579,6 +582,7 @@ module ts {
579582
case SyntaxKind.StringKeyword:
580583
case SyntaxKind.NumberKeyword:
581584
case SyntaxKind.BooleanKeyword:
585+
case SyntaxKind.SymbolKeyword:
582586
case SyntaxKind.VoidKeyword:
583587
case SyntaxKind.StringLiteral:
584588
return writeTextOfNode(currentSourceFile, type);

src/compiler/parser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,6 +2598,7 @@ module ts {
25982598
case SyntaxKind.StringKeyword:
25992599
case SyntaxKind.NumberKeyword:
26002600
case SyntaxKind.BooleanKeyword:
2601+
case SyntaxKind.SymbolKeyword:
26012602
// If these are followed by a dot, then parse these out as a dotted type reference instead.
26022603
var node = tryParse(parseKeywordAndNoDot);
26032604
return node || parseTypeReference();
@@ -2622,6 +2623,7 @@ module ts {
26222623
case SyntaxKind.StringKeyword:
26232624
case SyntaxKind.NumberKeyword:
26242625
case SyntaxKind.BooleanKeyword:
2626+
case SyntaxKind.SymbolKeyword:
26252627
case SyntaxKind.VoidKeyword:
26262628
case SyntaxKind.TypeOfKeyword:
26272629
case SyntaxKind.OpenBraceToken:

src/compiler/scanner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module ts {
8282
"string": SyntaxKind.StringKeyword,
8383
"super": SyntaxKind.SuperKeyword,
8484
"switch": SyntaxKind.SwitchKeyword,
85+
"symbol": SyntaxKind.SymbolKeyword,
8586
"this": SyntaxKind.ThisKeyword,
8687
"throw": SyntaxKind.ThrowKeyword,
8788
"true": SyntaxKind.TrueKeyword,

src/compiler/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ module ts {
140140
NumberKeyword,
141141
SetKeyword,
142142
StringKeyword,
143+
SymbolKeyword,
143144
TypeKeyword,
144145
OfKeyword,
145146
// Parse tree nodes
@@ -1304,9 +1305,10 @@ module ts {
13041305
ObjectLiteral = 0x00020000, // Originates in an object literal
13051306
ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type
13061307
ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type
1308+
ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6
13071309

1308-
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
1309-
Primitive = String | Number | Boolean | Void | Undefined | Null | StringLiteral | Enum,
1310+
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
1311+
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
13101312
StringLike = String | StringLiteral,
13111313
NumberLike = Number | Enum,
13121314
ObjectType = Class | Interface | Reference | Tuple | Anonymous,

src/compiler/utilities.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,54 @@ module ts {
838838
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
839839
}
840840

841+
/**
842+
* A declaration has a dynamic name if both of the following are true:
843+
* 1. The declaration has a computed property name
844+
* 2. The computed name is *not* expressed as Symbol.<name>, where name
845+
* is a property of the Symbol constructor that denotes a built in
846+
* Symbol.
847+
*/
848+
export function hasDynamicName(declaration: Declaration): boolean {
849+
return declaration.name &&
850+
declaration.name.kind === SyntaxKind.ComputedPropertyName &&
851+
!isWellKnownSymbolSyntactically((<ComputedPropertyName>declaration.name).expression);
852+
}
853+
854+
/**
855+
* Checks if the expression is of the form:
856+
* Symbol.name
857+
* where Symbol is literally the word "Symbol", and name is any identifierName
858+
*/
859+
export function isWellKnownSymbolSyntactically(node: Expression): boolean {
860+
return node.kind === SyntaxKind.PropertyAccessExpression && isESSymbolIdentifier((<PropertyAccessExpression>node).expression);
861+
}
862+
863+
export function getPropertyNameForPropertyNameNode(name: DeclarationName): string {
864+
if (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
865+
return (<Identifier | LiteralExpression>name).text;
866+
}
867+
if (name.kind === SyntaxKind.ComputedPropertyName) {
868+
var nameExpression = (<ComputedPropertyName>name).expression;
869+
if (isWellKnownSymbolSyntactically(nameExpression)) {
870+
var rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
871+
return getPropertyNameForKnownSymbolName(rightHandSideName);
872+
}
873+
}
874+
875+
return undefined;
876+
}
877+
878+
export function getPropertyNameForKnownSymbolName(symbolName: string): string {
879+
return "__@" + symbolName;
880+
}
881+
882+
/**
883+
* Includes the word "Symbol" with unicode escapes
884+
*/
885+
export function isESSymbolIdentifier(node: Node): boolean {
886+
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
887+
}
888+
841889
export function isModifier(token: SyntaxKind): boolean {
842890
switch (token) {
843891
case SyntaxKind.PublicKeyword:

0 commit comments

Comments
 (0)