Skip to content

Commit 4aa4ea7

Browse files
committed
allow arithmetic operations in constant expressions, handle infinity\NaN results
1 parent e949eda commit 4aa4ea7

File tree

6 files changed

+70
-4
lines changed

6 files changed

+70
-4
lines changed

src/compiler/checker.ts

+14
Original file line numberDiff line numberDiff line change
@@ -7686,6 +7686,15 @@ module ts {
76867686
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
76877687
}
76887688
}
7689+
else if (enumIsConst) {
7690+
if (isNaN(autoValue)) {
7691+
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_NaN);
7692+
}
7693+
else if (!isFinite(autoValue)) {
7694+
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_number);
7695+
}
7696+
}
7697+
76897698
}
76907699
else if (ambient && !enumIsConst) {
76917700
autoValue = undefined;
@@ -7735,6 +7744,11 @@ module ts {
77357744
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return left >>> right;
77367745
case SyntaxKind.LessThanLessThanToken: return left << right;
77377746
case SyntaxKind.CaretToken: return left ^ right;
7747+
case SyntaxKind.AsteriskToken: return left * right;
7748+
case SyntaxKind.SlashToken: return left / right;
7749+
case SyntaxKind.PlusToken: return left + right;
7750+
case SyntaxKind.MinusToken: return left - right;
7751+
case SyntaxKind.PercentToken: return left % right;
77387752
}
77397753
return undefined;
77407754
case SyntaxKind.NumericLiteral:

src/compiler/diagnosticInformationMap.generated.ts

+2
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ module ts {
354354
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 4083, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." },
355355
const_enums_can_only_be_used_in_property_access_expressions: { code: 4084, category: DiagnosticCategory.Error, key: "'const' enums can only be used in property access expressions." },
356356
Index_expression_arguments_in_const_enums_must_be_of_type_string: { code: 4085, category: DiagnosticCategory.Error, key: "Index expression arguments in 'const' enums must be of type 'string'." },
357+
const_enum_member_initializer_was_evaluated_to_a_non_finite_number: { code: 4086, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to a non-finite number." },
358+
const_enum_member_initializer_was_evaluated_to_NaN: { code: 4087, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to NaN." },
357359
The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." },
358360
Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." },
359361
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },

src/compiler/diagnosticMessages.json

+8
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,14 @@
14171417
"category": "Error",
14181418
"code": 4085
14191419
},
1420+
"'const' enum member initializer was evaluated to a non-finite number.": {
1421+
"category": "Error",
1422+
"code": 4086
1423+
},
1424+
"'const' enum member initializer was evaluated to NaN.": {
1425+
"category": "Error",
1426+
"code": 4087
1427+
},
14201428
"The current host does not support the '{0}' option.": {
14211429
"category": "Error",
14221430
"code": 5001

tests/baselines/reference/constEnumErrors.errors.txt

+22-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ tests/cases/compiler/constEnumErrors.ts(24,13): error TS4085: Index expression a
88
tests/cases/compiler/constEnumErrors.ts(26,9): error TS4084: 'const' enums can only be used in property access expressions.
99
tests/cases/compiler/constEnumErrors.ts(27,10): error TS4084: 'const' enums can only be used in property access expressions.
1010
tests/cases/compiler/constEnumErrors.ts(32,5): error TS4084: 'const' enums can only be used in property access expressions.
11+
tests/cases/compiler/constEnumErrors.ts(40,9): error TS4086: 'const' enum member initializer was evaluated to a non-finite number.
12+
tests/cases/compiler/constEnumErrors.ts(41,9): error TS4086: 'const' enum member initializer was evaluated to a non-finite number.
13+
tests/cases/compiler/constEnumErrors.ts(42,9): error TS4087: 'const' enum member initializer was evaluated to NaN.
1114

1215

13-
==== tests/cases/compiler/constEnumErrors.ts (10 errors) ====
16+
==== tests/cases/compiler/constEnumErrors.ts (13 errors) ====
1417
const enum E {
1518
~
1619
!!! error TS2300: Duplicate identifier 'E'.
@@ -62,4 +65,21 @@ tests/cases/compiler/constEnumErrors.ts(32,5): error TS4084: 'const' enums can o
6265

6366
foo(E2);
6467
~~
65-
!!! error TS4084: 'const' enums can only be used in property access expressions.
68+
!!! error TS4084: 'const' enums can only be used in property access expressions.
69+
70+
const enum NaNOrInfinity {
71+
A = 9007199254740992,
72+
B = A * A,
73+
C = B * B,
74+
D = C * C,
75+
E = D * D,
76+
F = E * E, // overflow
77+
~~~~~
78+
!!! error TS4086: 'const' enum member initializer was evaluated to a non-finite number.
79+
G = 1 / 0, // overflow
80+
~~~~~
81+
!!! error TS4086: 'const' enum member initializer was evaluated to a non-finite number.
82+
H = 0 / 0 // NaN
83+
~~~~~
84+
!!! error TS4087: 'const' enum member initializer was evaluated to NaN.
85+
}

tests/baselines/reference/constEnumErrors.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,18 @@ var y = [E2];
3030
function foo(t: any): void {
3131
}
3232

33-
foo(E2);
33+
foo(E2);
34+
35+
const enum NaNOrInfinity {
36+
A = 9007199254740992,
37+
B = A * A,
38+
C = B * B,
39+
D = C * C,
40+
E = D * D,
41+
F = E * E, // overflow
42+
G = 1 / 0, // overflow
43+
H = 0 / 0 // NaN
44+
}
3445

3546
//// [constEnumErrors.js]
3647
var E;

tests/cases/compiler/constEnumErrors.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,15 @@ var y = [E2];
2929
function foo(t: any): void {
3030
}
3131

32-
foo(E2);
32+
foo(E2);
33+
34+
const enum NaNOrInfinity {
35+
A = 9007199254740992,
36+
B = A * A,
37+
C = B * B,
38+
D = C * C,
39+
E = D * D,
40+
F = E * E, // overflow
41+
G = 1 / 0, // overflow
42+
H = 0 / 0 // NaN
43+
}

0 commit comments

Comments
 (0)