mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
fix(46195): handle numeric separators and larger integers correctly in codefix for large integers (#46389)
* fix(46195): handle numeric separators and larger integers correctly * Use `indexOf()` instead of `includes()`
This commit is contained in:
@@ -43906,19 +43906,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkNumericLiteralValueSize(node: NumericLiteral) {
|
||||
// We should test against `getTextOfNode(node)` rather than `node.text`, because `node.text` for large numeric literals can contain "."
|
||||
// e.g. `node.text` for numeric literal `1100000000000000000000` is `1.1e21`.
|
||||
const isFractional = getTextOfNode(node).indexOf(".") !== -1;
|
||||
const isScientific = node.numericLiteralFlags & TokenFlags.Scientific;
|
||||
|
||||
// Scientific notation (e.g. 2e54 and 1e00000000010) can't be converted to bigint
|
||||
// Literals with 15 or fewer characters aren't long enough to reach past 2^53 - 1
|
||||
// Fractional numbers (e.g. 9000000000000000.001) are inherently imprecise anyway
|
||||
if (node.numericLiteralFlags & TokenFlags.Scientific || node.text.length <= 15 || node.text.indexOf(".") !== -1) {
|
||||
if (isFractional || isScientific) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We can't rely on the runtime to accurately store and compare extremely large numeric values
|
||||
// Even for internal use, we use getTextOfNode: https://github.com/microsoft/TypeScript/issues/33298
|
||||
// Thus, if the runtime claims a too-large number is lower than Number.MAX_SAFE_INTEGER,
|
||||
// it's likely addition operations on it will fail too
|
||||
const apparentValue = +getTextOfNode(node);
|
||||
if (apparentValue <= 2 ** 53 - 1 && apparentValue + 1 > apparentValue) {
|
||||
// Here `node` is guaranteed to be a numeric literal representing an integer.
|
||||
// We need to judge whether the integer `node` represents is <= 2 ** 53 - 1, which can be accomplished by comparing to `value` defined below because:
|
||||
// 1) when `node` represents an integer <= 2 ** 53 - 1, `node.text` is its exact string representation and thus `value` precisely represents the integer.
|
||||
// 2) otherwise, although `node.text` may be imprecise string representation, its mathematical value and consequently `value` cannot be less than 2 ** 53,
|
||||
// thus the result of the predicate won't be affected.
|
||||
const value = +node.text;
|
||||
if (value <= 2 ** 53 - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
17
tests/cases/fourslash/codeFixUseBigIntLiteral2.ts
Normal file
17
tests/cases/fourslash/codeFixUseBigIntLiteral2.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
////1000000000000000000000; // 1e21
|
||||
////1_000_000_000_000_000_000_000; // 1e21
|
||||
////0x3635C9ADC5DEA00000; // 1e21
|
||||
////100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; // 1e320
|
||||
////100_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000; // 1e320
|
||||
|
||||
verify.codeFixAll({
|
||||
fixAllDescription: ts.Diagnostics.Convert_all_to_bigint_numeric_literals.message,
|
||||
fixId: "useBigintLiteral",
|
||||
newFileContent:
|
||||
`1000000000000000000000n; // 1e21
|
||||
1_000_000_000_000_000_000_000n; // 1e21
|
||||
0x3635C9ADC5DEA00000n; // 1e21
|
||||
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n; // 1e320
|
||||
100_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000n; // 1e320`,
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
////6_402_373_705_728_000; // 18! < 2 ** 53
|
||||
////0x16_BE_EC_CA_73_00_00; // 18! < 2 ** 53
|
||||
|
||||
verify.not.codeFixAvailable("useBigintLiteral");
|
||||
Reference in New Issue
Block a user