Skip to content

Commit eeb4dc4

Browse files
committed
Merge branch 'master' into computedProperties
2 parents 768d818 + 2052ac3 commit eeb4dc4

15 files changed

Lines changed: 1633 additions & 85 deletions

src/compiler/binder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ module ts {
99

1010
export function getModuleInstanceState(node: Node): ModuleInstanceState {
1111
// A module is uninstantiated if it contains only
12-
// 1. interface declarations
13-
if (node.kind === SyntaxKind.InterfaceDeclaration) {
12+
// 1. interface declarations, type alias declarations
13+
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) {
1414
return ModuleInstanceState.NonInstantiated;
1515
}
1616
// 2. const enum declarations don't make module instantiated

src/compiler/checker.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5644,7 +5644,7 @@ module ts {
56445644
}
56455645

56465646
var isConstEnum = isConstEnumObjectType(objectType);
5647-
if (isConstEnum &&
5647+
if (isConstEnum &&
56485648
(!node.argumentExpression || node.argumentExpression.kind !== SyntaxKind.StringLiteral)) {
56495649
error(node.argumentExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
56505650
return unknownType;
@@ -5676,10 +5676,10 @@ module ts {
56765676
}
56775677

56785678
// Check for compatible indexer types.
5679-
if (indexType.flags & (TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
5679+
if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
56805680

56815681
// Try to use a number indexer.
5682-
if (indexType.flags & (TypeFlags.Any | TypeFlags.NumberLike)) {
5682+
if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) {
56835683
var numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number);
56845684
if (numberIndexType) {
56855685
return numberIndexType;
@@ -6580,7 +6580,7 @@ module ts {
65806580
}
65816581

65826582
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
6583-
if (!(type.flags & (TypeFlags.Any | TypeFlags.NumberLike))) {
6583+
if (!isTypeOfKind(type, TypeFlags.Any | TypeFlags.NumberLike)) {
65846584
error(operand, diagnostic);
65856585
return false;
65866586
}
@@ -6731,12 +6731,21 @@ module ts {
67316731
return numberType;
67326732
}
67336733

6734-
// Return true if type an object type, a type parameter, or a union type composed of only those kinds of types
6735-
function isStructuredType(type: Type): boolean {
6734+
// Return true if type has the given flags, or is a union type composed of types that all have those flags
6735+
function isTypeOfKind(type: Type, kind: TypeFlags): boolean {
6736+
if (type.flags & kind) {
6737+
return true;
6738+
}
67366739
if (type.flags & TypeFlags.Union) {
6737-
return !forEach((<UnionType>type).types, t => !isStructuredType(t));
6740+
var types = (<UnionType>type).types;
6741+
for (var i = 0; i < types.length; i++) {
6742+
if (!(types[i].flags & kind)) {
6743+
return false;
6744+
}
6745+
}
6746+
return true;
67386747
}
6739-
return (type.flags & (TypeFlags.ObjectType | TypeFlags.TypeParameter)) !== 0;
6748+
return false;
67406749
}
67416750

67426751
function isConstEnumObjectType(type: Type): boolean {
@@ -6753,7 +6762,7 @@ module ts {
67536762
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
67546763
// The result is always of the Boolean primitive type.
67556764
// NOTE: do not raise error if leftType is unknown as related error was already reported
6756-
if (!(leftType.flags & TypeFlags.Any || isStructuredType(leftType))) {
6765+
if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
67576766
error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
67586767
}
67596768
// NOTE: do not raise error if right is unknown as related error was already reported
@@ -6768,10 +6777,10 @@ module ts {
67686777
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
67696778
// and the right operand to be of type Any, an object type, or a type parameter type.
67706779
// The result is always of the Boolean primitive type.
6771-
if (leftType !== anyType && leftType !== stringType && leftType !== numberType) {
6780+
if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
67726781
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
67736782
}
6774-
if (!(rightType.flags & TypeFlags.Any || isStructuredType(rightType))) {
6783+
if (!isTypeOfKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
67756784
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
67766785
}
67776786
return booleanType;
@@ -6932,16 +6941,16 @@ module ts {
69326941
if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType;
69336942

69346943
var resultType: Type;
6935-
if (leftType.flags & TypeFlags.NumberLike && rightType.flags & TypeFlags.NumberLike) {
6944+
if (isTypeOfKind(leftType, TypeFlags.NumberLike) && isTypeOfKind(rightType, TypeFlags.NumberLike)) {
69366945
// Operands of an enum type are treated as having the primitive type Number.
69376946
// If both operands are of the Number primitive type, the result is of the Number primitive type.
69386947
resultType = numberType;
69396948
}
6940-
else if (leftType.flags & TypeFlags.StringLike || rightType.flags & TypeFlags.StringLike) {
6949+
else if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) {
69416950
// If one or both operands are of the String primitive type, the result is of the String primitive type.
69426951
resultType = stringType;
69436952
}
6944-
else if (leftType.flags & TypeFlags.Any || leftType === unknownType || rightType.flags & TypeFlags.Any || rightType === unknownType) {
6953+
else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
69456954
// Otherwise, the result is of type Any.
69466955
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
69476956
resultType = anyType;
@@ -8315,7 +8324,7 @@ module ts {
83158324
var exprType = checkExpression(node.expression);
83168325
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
83178326
// in this case error about missing name is already reported - do not report extra one
8318-
if (!(exprType.flags & TypeFlags.Any || isStructuredType(exprType))) {
8327+
if (!isTypeOfKind(exprType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
83198328
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
83208329
}
83218330

tests/baselines/reference/additionOperatorWithNumberAndEnum.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//// [additionOperatorWithNumberAndEnum.ts]
22
enum E { a, b }
3+
enum F { c, d }
34

45
var a: number;
56
var b: E;
7+
var c: E | F;
68

79
var r1 = a + a;
810
var r2 = a + b;
@@ -12,16 +14,30 @@ var r4 = b + b;
1214
var r5 = 0 + a;
1315
var r6 = E.a + 0;
1416
var r7 = E.a + E.b;
15-
var r8 = E['a'] + E['b'];
17+
var r8 = E['a'] + E['b'];
18+
var r9 = E['a'] + F['c'];
19+
20+
var r10 = a + c;
21+
var r11 = c + a;
22+
var r12 = b + c;
23+
var r13 = c + b;
24+
var r14 = c + c;
25+
1626

1727
//// [additionOperatorWithNumberAndEnum.js]
1828
var E;
1929
(function (E) {
2030
E[E["a"] = 0] = "a";
2131
E[E["b"] = 1] = "b";
2232
})(E || (E = {}));
33+
var F;
34+
(function (F) {
35+
F[F["c"] = 0] = "c";
36+
F[F["d"] = 1] = "d";
37+
})(F || (F = {}));
2338
var a;
2439
var b;
40+
var c;
2541
var r1 = a + a;
2642
var r2 = a + b;
2743
var r3 = b + a;
@@ -30,3 +46,9 @@ var r5 = 0 + a;
3046
var r6 = 0 /* a */ + 0;
3147
var r7 = 0 /* a */ + 1 /* b */;
3248
var r8 = 0 /* 'a' */ + 1 /* 'b' */;
49+
var r9 = 0 /* 'a' */ + 0 /* 'c' */;
50+
var r10 = a + c;
51+
var r11 = c + a;
52+
var r12 = b + c;
53+
var r13 = c + b;
54+
var r14 = c + c;

tests/baselines/reference/additionOperatorWithNumberAndEnum.types

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ enum E { a, b }
44
>a : E
55
>b : E
66

7+
enum F { c, d }
8+
>F : F
9+
>c : F
10+
>d : F
11+
712
var a: number;
813
>a : number
914

1015
var b: E;
1116
>b : E
1217
>E : E
1318

19+
var c: E | F;
20+
>c : E | F
21+
>E : E
22+
>F : F
23+
1424
var r1 = a + a;
1525
>r1 : number
1626
>a + a : number
@@ -65,3 +75,41 @@ var r8 = E['a'] + E['b'];
6575
>E['b'] : E
6676
>E : typeof E
6777

78+
var r9 = E['a'] + F['c'];
79+
>r9 : number
80+
>E['a'] + F['c'] : number
81+
>E['a'] : E
82+
>E : typeof E
83+
>F['c'] : F
84+
>F : typeof F
85+
86+
var r10 = a + c;
87+
>r10 : number
88+
>a + c : number
89+
>a : number
90+
>c : E | F
91+
92+
var r11 = c + a;
93+
>r11 : number
94+
>c + a : number
95+
>c : E | F
96+
>a : number
97+
98+
var r12 = b + c;
99+
>r12 : number
100+
>b + c : number
101+
>b : E
102+
>c : E | F
103+
104+
var r13 = c + b;
105+
>r13 : number
106+
>c + b : number
107+
>c : E | F
108+
>b : E
109+
110+
var r14 = c + c;
111+
>r14 : number
112+
>c + c : number
113+
>c : E | F
114+
>c : E | F
115+

0 commit comments

Comments
 (0)