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,
|
||||
objectProperty,
|
||||
objectExpression,
|
||||
unaryExpression,
|
||||
binaryExpression,
|
||||
} from "../builders/generated";
|
||||
|
||||
export default function valueToNode(value: any): Object {
|
||||
@ -37,7 +39,27 @@ export default function valueToNode(value: any): Object {
|
||||
|
||||
// numbers
|
||||
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
|
||||
|
||||
@ -19,8 +19,29 @@ describe("converters", function() {
|
||||
describe("valueToNode", function() {
|
||||
it("number", function() {
|
||||
expect(t.valueToNode(Math.PI)).toEqual(t.numericLiteral(Math.PI));
|
||||
expect(t.valueToNode(-Infinity)).toEqual(t.numericLiteral(-Infinity));
|
||||
expect(t.valueToNode(NaN)).toEqual(t.numericLiteral(NaN));
|
||||
expect(t.valueToNode(-Math.PI)).toEqual(
|
||||
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() {
|
||||
expect(t.valueToNode('This is a "string"')).toEqual(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user