Handle Infinity, -Infinity, NaN, and -0 in t.valueToNode(). (#8005)
| Q | A <!--(Can use an emoji 👍) --> | ------------------------ | --- | Fixed Issues? | Fixes #8001 | Patch: Bug Fix? | Y | Major: Breaking Change? | Not unless things were relying on a very specific AST structure as output | Minor: New Feature? | | Tests Added + Pass? | Yes | Documentation PR | <!-- If so, add `[skip ci]` to your commit message to skip CI --> | Any Dependency Changes? | | License | MIT The filed bug was for `-0`, but I also realize that `numericLiteral` also shouldn't be getting `-Infinity`/`Infinity` or `NaN` since those just get stringified with the JS-standard stringification logic which means we get a reference to `NaN` or `Infinity` identifiers, which could have been shadowed in a local scope and thus not be the right value. I've avoided that by generating `NaN` as `0/0` and the infinity values as `1/0` and `-1/0`.
This commit is contained in:
parent
b4d18f4764
commit
5e00c96368
@ -12,6 +12,8 @@ import {
|
|||||||
arrayExpression,
|
arrayExpression,
|
||||||
objectProperty,
|
objectProperty,
|
||||||
objectExpression,
|
objectExpression,
|
||||||
|
unaryExpression,
|
||||||
|
binaryExpression,
|
||||||
} from "../builders/generated";
|
} from "../builders/generated";
|
||||||
|
|
||||||
export default function valueToNode(value: any): Object {
|
export default function valueToNode(value: any): Object {
|
||||||
@ -37,7 +39,27 @@ export default function valueToNode(value: any): Object {
|
|||||||
|
|
||||||
// numbers
|
// numbers
|
||||||
if (typeof value === "number") {
|
if (typeof value === "number") {
|
||||||
return numericLiteral(value);
|
let result;
|
||||||
|
if (Number.isFinite(value)) {
|
||||||
|
result = numericLiteral(Math.abs(value));
|
||||||
|
} else {
|
||||||
|
let numerator;
|
||||||
|
if (Number.isNaN(value)) {
|
||||||
|
// NaN
|
||||||
|
numerator = numericLiteral(0);
|
||||||
|
} else {
|
||||||
|
// Infinity / -Infinity
|
||||||
|
numerator = numericLiteral(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = binaryExpression("/", numerator, numericLiteral(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 0 || Object.is(value, -0)) {
|
||||||
|
result = unaryExpression("-", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// regexes
|
// regexes
|
||||||
|
|||||||
@ -19,8 +19,29 @@ describe("converters", function() {
|
|||||||
describe("valueToNode", function() {
|
describe("valueToNode", function() {
|
||||||
it("number", function() {
|
it("number", function() {
|
||||||
expect(t.valueToNode(Math.PI)).toEqual(t.numericLiteral(Math.PI));
|
expect(t.valueToNode(Math.PI)).toEqual(t.numericLiteral(Math.PI));
|
||||||
expect(t.valueToNode(-Infinity)).toEqual(t.numericLiteral(-Infinity));
|
expect(t.valueToNode(-Math.PI)).toEqual(
|
||||||
expect(t.valueToNode(NaN)).toEqual(t.numericLiteral(NaN));
|
t.unaryExpression("-", t.numericLiteral(Math.PI)),
|
||||||
|
);
|
||||||
|
expect(t.valueToNode(0)).toEqual(t.numericLiteral(0));
|
||||||
|
expect(t.valueToNode(-0)).toEqual(
|
||||||
|
t.unaryExpression("-", t.numericLiteral(0)),
|
||||||
|
);
|
||||||
|
expect(t.valueToNode(NaN)).toEqual(
|
||||||
|
t.binaryExpression("/", t.numericLiteral(0), t.numericLiteral(0)),
|
||||||
|
);
|
||||||
|
expect(t.valueToNode(-NaN)).toEqual(
|
||||||
|
t.binaryExpression("/", t.numericLiteral(0), t.numericLiteral(0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(t.valueToNode(Infinity)).toEqual(
|
||||||
|
t.binaryExpression("/", t.numericLiteral(1), t.numericLiteral(0)),
|
||||||
|
);
|
||||||
|
expect(t.valueToNode(-Infinity)).toEqual(
|
||||||
|
t.unaryExpression(
|
||||||
|
"-",
|
||||||
|
t.binaryExpression("/", t.numericLiteral(1), t.numericLiteral(0)),
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it("string", function() {
|
it("string", function() {
|
||||||
expect(t.valueToNode('This is a "string"')).toEqual(
|
expect(t.valueToNode('This is a "string"')).toEqual(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user