Skip to content

Commit

Permalink
[babel 8] Numeric literals must be finite and non-negative (#15802)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Jul 21, 2023
1 parent 1010563 commit 3d47fb6
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 23 deletions.
17 changes: 13 additions & 4 deletions packages/babel-plugin-transform-typescript/src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,20 @@ export function translateEnumValues(path: NodePath<t.TSEnumDeclaration>, t: t) {
constValue = computeConstantValue(initializerPath, seen);
if (constValue !== undefined) {
seen.set(name, constValue);
if (typeof constValue === "number") {
value = t.numericLiteral(constValue);
assert(
typeof constValue === "number" || typeof constValue === "string",
);
// We do not use `t.valueToNode` because `Infinity`/`NaN` might refer
// to a local variable. Even 1/0
// Revisit once https://github.com/microsoft/TypeScript/issues/55091
// is fixed. Note: we will have to distinguish between actual
// infinities and reference to non-infinite variables names Infinity.
if (constValue === Infinity || Number.isNaN(constValue)) {
value = t.identifier(String(constValue));
} else if (constValue === -Infinity) {
value = t.unaryExpression("-", t.identifier("Infinity"));
} else {
assert(typeof constValue === "string");
value = t.stringLiteral(constValue);
value = t.valueToNode(constValue);
}
} else {
isPure &&= initializerPath.isPure();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
const v = 42;
const v2 = Infinity;
var Infinity = 1; // Known inconsistencies
enum StateEnum {
okay = 0,
neg = -Infinity,
pos = Infinity,
nan = NaN,
ext = v,
ext2 = v2,
const v3 = NaN;

{
let Infinity = 1;
let NaN = 2;

enum StateEnum {
okay = 0,
neg = -Infinity,
pos = Infinity,
nan = NaN,
negReal = -1 / 0,
posReal = 1 / 0,
nanReal = 0 / 0,
ext = v,
ext2 = v2,
ext3 = v3,
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
const v = 42;
const v2 = Infinity;
var Infinity = 1; // Known inconsistencies
var StateEnum = /*#__PURE__*/function (StateEnum) {
StateEnum[StateEnum["okay"] = 0] = "okay";
StateEnum[StateEnum["neg"] = -Infinity] = "neg";
StateEnum[StateEnum["pos"] = Infinity] = "pos";
StateEnum[StateEnum["nan"] = NaN] = "nan";
StateEnum[StateEnum["ext"] = 42] = "ext";
StateEnum[StateEnum["ext2"] = 1] = "ext2";
return StateEnum;
}(StateEnum || {});
const v3 = NaN;
{
let Infinity = 1;
let NaN = 2;
let StateEnum = /*#__PURE__*/function (StateEnum) {
StateEnum[StateEnum["okay"] = 0] = "okay";
StateEnum[StateEnum["neg"] = -Infinity] = "neg";
StateEnum[StateEnum["pos"] = Infinity] = "pos";
StateEnum[StateEnum["nan"] = NaN] = "nan";
StateEnum[StateEnum["negReal"] = -Infinity] = "negReal";
StateEnum[StateEnum["posReal"] = Infinity] = "posReal";
StateEnum[StateEnum["nanReal"] = NaN] = "nanReal";
StateEnum[StateEnum["ext"] = 42] = "ext";
StateEnum[StateEnum["ext2"] = Infinity] = "ext2";
StateEnum[StateEnum["ext3"] = NaN] = "ext3";
return StateEnum;
}({});
}
3 changes: 3 additions & 0 deletions packages/babel-types/scripts/generators/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const customTypes = {
ClassPrivateProperty: {
computed: "'false'",
},
NumericLiteral: {
value: "a non-negative finite `number`",
},
};
const APIHistory = {
ClassProperty: [["v7.6.0", "Supports `static`"]],
Expand Down
28 changes: 27 additions & 1 deletion packages/babel-types/src/definitions/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,33 @@ defineType("NumericLiteral", {
deprecatedAlias: "NumberLiteral",
fields: {
value: {
validate: assertValueType("number"),
validate: chain(
assertValueType("number"),
Object.assign(
function (node, key, val) {
if (1 / val < 0 || !Number.isFinite(val)) {
const error = new Error(
"NumericLiterals must be non-negative finite numbers. " +
`You can use t.valueToNode(${val}) instead.`,
);
if (process.env.BABEL_8_BREAKING) {
// TODO(@nicolo-ribaudo) Fix regenerator to not pass negative
// numbers here.
if (!IS_STANDALONE) {
if (!new Error().stack.includes("regenerator")) {
throw error;
}
}
} else {
// TODO: Enable this warning once regenerator is fixed.
// https://github.com/facebook/regenerator/pull/680
// console.warn(error);
}
}
} satisfies Validator,
{ type: "number" },
),
),
},
},
aliases: ["Expression", "Pureish", "Literal", "Immutable"],
Expand Down
13 changes: 13 additions & 0 deletions packages/babel-types/test/builders/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as t from "../../lib/index.js";

const itBabel8 = process.env.BABEL_8_BREAKING ? it : it.skip;

describe("builders", function () {
itBabel8("t.numericLiteral expexts a non-negative finite value", () => {
expect(() => t.numericLiteral(-1)).toThrow();
expect(() => t.numericLiteral(-0)).toThrow();
expect(() => t.numericLiteral(-Infinity)).toThrow();
expect(() => t.numericLiteral(Infinity)).toThrow();
expect(() => t.numericLiteral(NaN)).toThrow();
});
});

0 comments on commit 3d47fb6

Please sign in to comment.