Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
11d75ef
Allow Symbol indexer in ES6
JsonFreeman Jan 26, 2015
b30d8f3
Change computed property error messages to be about symbols
JsonFreeman Jan 28, 2015
39952b1
Syntactically allow computed properties everywhere if the name looks …
JsonFreeman Jan 28, 2015
d788624
Move hasDynamicName to utilities.ts
JsonFreeman Jan 28, 2015
07f3641
Update hasDynamicName to take well known symbols into account
JsonFreeman Jan 28, 2015
f344654
Add named property symbol for known Symbol properties
JsonFreeman Jan 28, 2015
30892af
Change computed property error message to mention Symbols
JsonFreeman Jan 29, 2015
9cb38fb
Create global Symbol type
JsonFreeman Jan 30, 2015
25fcbe2
Change certain hasDynamicName checks to check the SyntaxKind instead
JsonFreeman Jan 30, 2015
b60fa14
Add tests for operators with symbol operand
JsonFreeman Jan 30, 2015
779661c
Add tests for symbol properties
JsonFreeman Feb 2, 2015
95af997
Accept correct baselines for symbol property tests
JsonFreeman Feb 3, 2015
e508bf7
Add symbol keyword
JsonFreeman Feb 3, 2015
ebdd96b
Update tests to use new symbol keyword
JsonFreeman Feb 3, 2015
e346b70
Change isTypeOfKind calls to pass symbol TypeFlag when needed
JsonFreeman Feb 4, 2015
59a704e
Rename references in es6.d.ts from Symbol to symbol
JsonFreeman Feb 4, 2015
d793658
Change Symbol to symbol in error messages
JsonFreeman Feb 4, 2015
2d16474
Fix expression checking for symbols
JsonFreeman Feb 5, 2015
6a6c03b
Fix error message wording
JsonFreeman Feb 5, 2015
92617f5
Don't pass prop.name directly for error reporting
JsonFreeman Feb 5, 2015
fbeadbc
Add test for new Symbol()
JsonFreeman Feb 5, 2015
9f39a53
Make Symbol the apparent type of symbol
JsonFreeman Feb 5, 2015
df826de
symbols in type guards
JsonFreeman Feb 5, 2015
d07ed67
Support indexing with known symbols
JsonFreeman Feb 6, 2015
8325862
Fix error message
JsonFreeman Feb 6, 2015
3834edd
Refactor part of getPropertyNameForIndexedAccess into checkSymbolName…
JsonFreeman Feb 6, 2015
4c09ccd
Check that Symbol properties are proper, and support downlevel type c…
JsonFreeman Feb 7, 2015
3560442
Declaration emit for symbol properties
JsonFreeman Feb 7, 2015
2f3c32a
Navigation bar support for symbols
JsonFreeman Feb 7, 2015
eb50619
Disable symbol indexer
JsonFreeman Feb 7, 2015
52cb13e
Uncomment symbol properties in es6.d.ts
JsonFreeman Feb 7, 2015
75382c1
Accept baselines after rebase
JsonFreeman Feb 7, 2015
18276e5
Address feedback from @yuit
JsonFreeman Feb 11, 2015
a94e61b
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 11, 2015
486cebd
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 12, 2015
4942c5f
Address feedback
JsonFreeman Feb 13, 2015
9c273d8
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 13, 2015
65d831e
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 16, 2015
ac829a8
Error for naming an interface 'symbol'
JsonFreeman Feb 16, 2015
7d7d54f
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 16, 2015
935c602
Rebaseline after merge
JsonFreeman Feb 16, 2015
59dc7d3
Address feedback
JsonFreeman Feb 17, 2015
dd6a129
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 17, 2015
47404bc
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman Feb 18, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix expression checking for symbols
  • Loading branch information
JsonFreeman committed Feb 7, 2015
commit 2d1647485cfb33a7ae1d84a6bc08ced6f952a552
72 changes: 59 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6856,6 +6856,9 @@ module ts {
case SyntaxKind.PlusToken:
case SyntaxKind.MinusToken:
case SyntaxKind.TildeToken:
if (hasSomeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_a_value_of_type_symbol, tokenToString(node.operator));
}
return numberType;
case SyntaxKind.ExclamationToken:
return booleanType;
Expand Down Expand Up @@ -6891,6 +6894,24 @@ module ts {
return numberType;
}

// Just like isTypeOfKind below, except that it returns true if *any* constituent
// has this kind.
function hasSomeTypeOfKind(type: Type, kind: TypeFlags): boolean {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

someTypeHasKind

if (type.flags & kind) {
return true;
}
if (type.flags & TypeFlags.Union) {
var types = (<UnionType>type).types;
for (var i = 0; i < types.length; i++) {
if (types[i].flags & kind) {
return true;
}
}
return false;
}
return false;
}

// Return true if type has the given flags, or is a union type composed of types that all have those flags.
function isTypeOfKind(type: Type, kind: TypeFlags): boolean {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allTypesHaveKind

if (type.flags & kind) {
Expand Down Expand Up @@ -6938,7 +6959,7 @@ module ts {
// and the right operand to be of type Any, an object type, or a type parameter type.
// The result is always of the Boolean primitive type.
if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeOfKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
Expand Down Expand Up @@ -7106,14 +7127,21 @@ module ts {
// If both operands are of the Number primitive type, the result is of the Number primitive type.
resultType = numberType;
}
else if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) {
// If one or both operands are of the String primitive type, the result is of the String primitive type.
resultType = stringType;
}
else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
// Otherwise, the result is of type Any.
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
resultType = anyType;
else {
if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) {
// If one or both operands are of the String primitive type, the result is of the String primitive type.
resultType = stringType;
}
else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
// Otherwise, the result is of type Any.
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
resultType = anyType;
}

// Symbols are not allowed at all in arithmetic expressions
if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
return resultType;
}
}

if (!resultType) {
Expand All @@ -7125,14 +7153,18 @@ module ts {
checkAssignmentOperator(resultType);
}
return resultType;
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.GreaterThanToken:
case SyntaxKind.LessThanEqualsToken:
case SyntaxKind.GreaterThanEqualsToken:
if (!checkForDisallowedESSymbolOperand(operator)) {
return booleanType;
}
// Fall through
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
Expand All @@ -7152,6 +7184,20 @@ module ts {
return rightType;
}

// Return type is true if there was no error, false if there was an error.
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
var offendingSymbolOperand =
hasSomeTypeOfKind(leftType, TypeFlags.ESSymbol) ? node.left :
hasSomeTypeOfKind(rightType, TypeFlags.ESSymbol) ? node.right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_a_value_of_type_symbol, tokenToString(operator));
return false;
}

return true;
}

function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind {
switch (operator) {
case SyntaxKind.BarToken:
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ module ts {
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: { code: 2357, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator must be a variable, property or indexer." },
The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2358, category: DiagnosticCategory.Error, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." },
The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2359, category: DiagnosticCategory.Error, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." },
The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: { code: 2360, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'." },
The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: { code: 2360, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'." },
The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2361, category: DiagnosticCategory.Error, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" },
The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2362, category: DiagnosticCategory.Error, key: "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2363, category: DiagnosticCategory.Error, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
Expand Down Expand Up @@ -305,6 +305,7 @@ module ts {
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_containing_type: { code: 2467, category: DiagnosticCategory.Error, key: "A computed property name cannot reference a type parameter from its containing type." },
Cannot_find_global_value_0: { code: 2468, category: DiagnosticCategory.Error, key: "Cannot find global value '{0}'." },
The_0_operator_cannot_be_applied_to_a_value_of_type_symbol: { code: 2469, category: DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to a value of type 'symbol'." },
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}'." },
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@
"category": "Error",
"code": 2359
},
"The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.": {
"The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.": {
"category": "Error",
"code": 2360
},
Expand Down Expand Up @@ -1213,6 +1213,10 @@
"category": "Error",
"code": 2468
},
"The '{0}' operator cannot be applied to a value of type 'symbol'.": {
"category": "Error",
"code": 2469
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
32 changes: 16 additions & 16 deletions tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(31,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(32,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
Expand All @@ -15,7 +15,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(37,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(38,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(39,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter


Expand All @@ -33,27 +33,27 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv

var ra1 = a1 in x;
~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra2 = a2 in x;
~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra3 = a3 in x;
~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra4 = a4 in x;
var ra5 = null in x;
~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra6 = undefined in x;
~~~~~~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra7 = E.a in x;
var ra8 = false in x;
~~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra9 = {} in x;
~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.

// invalid right operands
// the right operand is required to be of type Any, an object type, or a type parameter type
Expand Down Expand Up @@ -98,6 +98,6 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
// both operands are invalid
var rc1 = {} in '';
~~
!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
~~
!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
9 changes: 9 additions & 0 deletions tests/baselines/reference/symbolProperty54.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
tests/cases/conformance/es6/Symbols/symbolProperty54.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.


==== tests/cases/conformance/es6/Symbols/symbolProperty54.ts (1 errors) ====
var obj = {
[Symbol.prototype]: 0
~~~~~~~~~~~~~~~~~~
!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
};
Loading