Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 24 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33663,9 +33663,9 @@ namespace ts {
}

function checkGrammarNumericLiteral(node: NumericLiteral): boolean {
// Grammar checking
let diagnosticMessage: DiagnosticMessage | undefined;

if (node.numericLiteralFlags & TokenFlags.Octal) {
let diagnosticMessage: DiagnosticMessage | undefined;
if (languageVersion >= ScriptTarget.ES5) {
diagnosticMessage = Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
}
Expand All @@ -33675,15 +33675,32 @@ namespace ts {
else if (isChildOfNodeWithKind(node, SyntaxKind.EnumMember)) {
diagnosticMessage = Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
}
if (diagnosticMessage) {
const withMinus = isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.MinusToken;
const literal = (withMinus ? "-" : "") + "0o" + node.text;
return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
}
}

if (!diagnosticMessage && numericLiteralValueImpreciselyLarge(node.text)) {
diagnosticMessage = Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_an_integer;
}

if (diagnosticMessage) {
const withMinus = isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.MinusToken;
const literal = (withMinus ? "-" : "") + "0o" + node.text;
return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
Copy link
Member

Choose a reason for hiding this comment

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

This is feeding in a userless literal parameter`. It's not a problem per se, but it is very weird to do.

}

return false;
}

function numericLiteralValueImpreciselyLarge(text: string) {
// We can quickly bail out in two common cases:
// * Literals with 15 or fewer characters, as they aren't long enough to reach 2^53 - 1
// * Fractional numbers (e.g. 9000000000000000000000000000.000000001) are inherently imprecise anyway
if (text.length <= 15 || text.indexOf(".") !== -1) {
Copy link
Member

@DanielRosenwasser DanielRosenwasser Sep 3, 2019

Choose a reason for hiding this comment

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

This doesn't check for other things like scientific notation (1000000000000000000000000000e1), but you can't do a simple indexOf on e because you don't want to allow 0xbeef.

return false;
}

return Number(text) >= Math.pow(2, 53) - 1;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, per the user baselines, should allow 9007199254740991 as 2**53. Will update...

Suggested change
return Number(text) >= Math.pow(2, 53) - 1;
return Number(text) >= 2 ** 53;

Copy link
Contributor

Choose a reason for hiding this comment

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

IE does not have the exponentiation operator, according to mdn

Copy link
Member

Choose a reason for hiding this comment

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

it gets downleveled

Copy link
Contributor

Choose a reason for hiding this comment

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

Right. I forgot TS down levels syntax, but not methods.

}

function checkGrammarBigIntLiteral(node: BigIntLiteral): boolean {
const literalType = isLiteralTypeNode(node.parent) ||
isPrefixUnaryExpression(node.parent) && isLiteralTypeNode(node.parent.parent);
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,10 @@
"category": "Error",
"code": 1356
},
"Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.": {
Copy link
Member

Choose a reason for hiding this comment

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

as integers

"category": "Error",
"code": 1357
},

"Duplicate identifier '{0}'.": {
"category": "Error",
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/constEnumErrors.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ tests/cases/compiler/constEnumErrors.ts(24,13): error TS2476: A const enum membe
tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.
tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.
tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.
tests/cases/compiler/constEnumErrors.ts(35,9): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/constEnumErrors.ts(40,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
tests/cases/compiler/constEnumErrors.ts(41,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.


==== tests/cases/compiler/constEnumErrors.ts (13 errors) ====
==== tests/cases/compiler/constEnumErrors.ts (14 errors) ====
const enum E {
~
!!! error TS2567: Enum declarations can only merge with namespace or other enum declarations.
Expand Down Expand Up @@ -69,6 +70,8 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member

const enum NaNOrInfinity {
A = 9007199254740992,
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
B = A * A,
C = B * B,
D = C * C,
Expand Down
201 changes: 201 additions & 0 deletions tests/baselines/reference/impreciseNumericLiterals.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
tests/cases/compiler/impreciseNumericLiterals.ts(33,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(34,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(35,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(36,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(37,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(38,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(39,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(40,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(46,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(47,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(48,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(49,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(50,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(51,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(81,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(82,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(83,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(84,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(85,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(86,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(87,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(88,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(108,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(109,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(110,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(111,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(112,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
tests/cases/compiler/impreciseNumericLiterals.ts(113,1): error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.


==== tests/cases/compiler/impreciseNumericLiterals.ts (28 errors) ====
1;
-1;
12;
-12;
123;
-123;
1234;
-1234;
12345;
-12345;
123456;
-123456;
1234567;
-1234567;
12345678;
-12345678;
123456789;
-123456789;
1234567890;
-1234567890;
12345678901;
-12345678901;
123456789012;
-123456789012;
1234567890123;
-1234567890123;
12345678901234;
-12345678901234;
123456789012345;
-123456789012345;
1234567890123456;
-1234567890123456;
12345678901234567;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-12345678901234567;
~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
123456789012345678;
~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-123456789012345678;
~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
1234567890123456789;
~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-1234567890123456789;
~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
12345678901234567890;
~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-12345678901234567890;
~~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.

9007199254740989;
-9007199254740989;
9007199254740990;
-9007199254740990;
9007199254740991;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-9007199254740991;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
9007199254740992;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-9007199254740992;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
9007199254740993;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-9007199254740993;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.

0x1;
-0x1;
0x12;
-0x12;
0x123;
-0x123;
0x1234;
-0x1234;
0x12345;
-0x12345;
0x123456;
-0x123456;
0x1234567;
-0x1234567;
0x12345678;
-0x12345678;
0x123456789;
-0x123456789;
0x1234567890;
-0x1234567890;
0x12345678901;
-0x12345678901;
0x123456789012;
-0x123456789012;
0x1234567890123;
-0x1234567890123;
0x12345678901234;
-0x12345678901234;
0x123456789012345;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x123456789012345;
~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x1234567890123456;
~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x1234567890123456;
~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x12345678901234567;
~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x12345678901234567;
~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x123456789012345678;
~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x123456789012345678;
~~~~~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x1234567890123456789;
-0x1234567890123456789;
0x12345678901234567890;
-0x12345678901234567890;
0x123456789012345678901;
-0x123456789012345678901;
0x1234567890123456789012;
-0x1234567890123456789012;
0x12345678901234567890123;
-0x12345678901234567890123;
0x123456789012345678901234;
-0x123456789012345678901234;
0x1234567890123456789012345;
-0x1234567890123456789012345;

0x19999999999998;
-0x19999999999998;
0x19999999999999;
-0x19999999999999;
0x20000000000000;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x20000000000000;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x20000000000001;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x20000000000001;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
0x20000000000002;
~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.
-0x20000000000002;
~~~~~~~~~~~~~~~~~
!!! error TS1357: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as an integer.

Loading