From 4aa4ea75d1cecb96fca6e2d57b4b62832c2d913b Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 29 Oct 2014 23:21:30 -0700 Subject: [PATCH] allow arithmetic operations in constant expressions, handle infinity\NaN results --- src/compiler/checker.ts | 14 +++++++++++ .../diagnosticInformationMap.generated.ts | 2 ++ src/compiler/diagnosticMessages.json | 8 +++++++ .../reference/constEnumErrors.errors.txt | 24 +++++++++++++++++-- tests/baselines/reference/constEnumErrors.js | 13 +++++++++- tests/cases/compiler/constEnumErrors.ts | 13 +++++++++- 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 02757e458c8..4af17b4bcb0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7686,6 +7686,15 @@ module ts { checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined); } } + else if (enumIsConst) { + if (isNaN(autoValue)) { + error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_NaN); + } + else if (!isFinite(autoValue)) { + error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_number); + } + } + } else if (ambient && !enumIsConst) { autoValue = undefined; @@ -7735,6 +7744,11 @@ module ts { case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return left >>> right; case SyntaxKind.LessThanLessThanToken: return left << right; case SyntaxKind.CaretToken: return left ^ right; + case SyntaxKind.AsteriskToken: return left * right; + case SyntaxKind.SlashToken: return left / right; + case SyntaxKind.PlusToken: return left + right; + case SyntaxKind.MinusToken: return left - right; + case SyntaxKind.PercentToken: return left % right; } return undefined; case SyntaxKind.NumericLiteral: diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 8bf05e403c8..525932fb428 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -354,6 +354,8 @@ module ts { 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." }, 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." }, 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'." }, + 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." }, + const_enum_member_initializer_was_evaluated_to_NaN: { code: 4087, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to NaN." }, The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." }, 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." }, Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9b9094223ce..3e79591e719 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1417,6 +1417,14 @@ "category": "Error", "code": 4085 }, + "'const' enum member initializer was evaluated to a non-finite number.": { + "category": "Error", + "code": 4086 + }, + "'const' enum member initializer was evaluated to NaN.": { + "category": "Error", + "code": 4087 + }, "The current host does not support the '{0}' option.": { "category": "Error", "code": 5001 diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 2464180ad34..21cc5a239d5 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -8,9 +8,12 @@ tests/cases/compiler/constEnumErrors.ts(24,13): error TS4085: Index expression a tests/cases/compiler/constEnumErrors.ts(26,9): error TS4084: 'const' enums can only be used in property access expressions. tests/cases/compiler/constEnumErrors.ts(27,10): error TS4084: 'const' enums can only be used in property access expressions. tests/cases/compiler/constEnumErrors.ts(32,5): error TS4084: 'const' enums can only be used in property access expressions. +tests/cases/compiler/constEnumErrors.ts(40,9): error TS4086: 'const' enum member initializer was evaluated to a non-finite number. +tests/cases/compiler/constEnumErrors.ts(41,9): error TS4086: 'const' enum member initializer was evaluated to a non-finite number. +tests/cases/compiler/constEnumErrors.ts(42,9): error TS4087: 'const' enum member initializer was evaluated to NaN. -==== tests/cases/compiler/constEnumErrors.ts (10 errors) ==== +==== tests/cases/compiler/constEnumErrors.ts (13 errors) ==== const enum E { ~ !!! error TS2300: Duplicate identifier 'E'. @@ -62,4 +65,21 @@ tests/cases/compiler/constEnumErrors.ts(32,5): error TS4084: 'const' enums can o foo(E2); ~~ -!!! error TS4084: 'const' enums can only be used in property access expressions. \ No newline at end of file +!!! error TS4084: 'const' enums can only be used in property access expressions. + + const enum NaNOrInfinity { + A = 9007199254740992, + B = A * A, + C = B * B, + D = C * C, + E = D * D, + F = E * E, // overflow + ~~~~~ +!!! error TS4086: 'const' enum member initializer was evaluated to a non-finite number. + G = 1 / 0, // overflow + ~~~~~ +!!! error TS4086: 'const' enum member initializer was evaluated to a non-finite number. + H = 0 / 0 // NaN + ~~~~~ +!!! error TS4087: 'const' enum member initializer was evaluated to NaN. + } \ No newline at end of file diff --git a/tests/baselines/reference/constEnumErrors.js b/tests/baselines/reference/constEnumErrors.js index 7a1260583df..4afd98982f0 100644 --- a/tests/baselines/reference/constEnumErrors.js +++ b/tests/baselines/reference/constEnumErrors.js @@ -30,7 +30,18 @@ var y = [E2]; function foo(t: any): void { } -foo(E2); +foo(E2); + +const enum NaNOrInfinity { + A = 9007199254740992, + B = A * A, + C = B * B, + D = C * C, + E = D * D, + F = E * E, // overflow + G = 1 / 0, // overflow + H = 0 / 0 // NaN +} //// [constEnumErrors.js] var E; diff --git a/tests/cases/compiler/constEnumErrors.ts b/tests/cases/compiler/constEnumErrors.ts index b77a4399284..87e6b7ccb98 100644 --- a/tests/cases/compiler/constEnumErrors.ts +++ b/tests/cases/compiler/constEnumErrors.ts @@ -29,4 +29,15 @@ var y = [E2]; function foo(t: any): void { } -foo(E2); \ No newline at end of file +foo(E2); + +const enum NaNOrInfinity { + A = 9007199254740992, + B = A * A, + C = B * B, + D = C * C, + E = D * D, + F = E * E, // overflow + G = 1 / 0, // overflow + H = 0 / 0 // NaN +} \ No newline at end of file