`++` and `--` prefix operators not serialized correctly with "soft" constant
overlookmotel opened this issue · 1 comments
Input:
// Sloppy mode
const f = function x() {
return ++x;
};
f.valueOf = () => 100;
module.exports = f;
Output:
const x = (x$0 => x$0 = function x() {
return +x$0;
})();
Object.assign(x, {
valueOf: (0, () => 100)
});
module.exports = x;
x
here is a constant, but a "soft" const which doesn't throw an error when assigned to in sloppy mode code.
The original function returns 101
, whereas the serialized function returns 100
.
The output would be correct if it was x++
, but for ++x
the function's body should be return +x$0 + 1;
.
NB x$0 + 1
(without the preceding +
) is insufficient. ++x
coerces x
to a number, whereas x + 1
may instead coerce 1
to a string, so +x$0
is required to ensure x is coerced to a number before + 1
.
Same problem with --x
.
Actually, even that doesn't cover where value is a BigInt.
const x = 100n;
export default () => x++;
or:
// Sloppy mode
const f = function x() {
return ++x;
};
f.valueOf = () => 100n;
module.exports = f;
If x
is a BigInt
, +x
throws error TypeError: Cannot convert a BigInt value to a number
.
Only way to cover this is:
++x
-> (n=>++n)(x)
x++
-> (n=>n++)(x)
--x
-> (n=>--n)(x)
x--
-> (n=>n--)(x)
i.e. Perform the original operation, but just don't assign the result to the constant var.