feat: backport bigint support to uglify-es from #4583
This commit is contained in:
parent
569757d14d
commit
fd35571f37
18
lib/ast.js
18
lib/ast.js
|
|
@ -1068,7 +1068,23 @@ var AST_Number = DEFNODE("Number", "value literal", {
|
|||
$propdoc: {
|
||||
value: "[number] the numeric value",
|
||||
literal: "[string] numeric value as string (optional)"
|
||||
}
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.value != "number") throw new Error("value must be number");
|
||||
if (!isFinite(this.value)) throw new Error("value must be finite");
|
||||
if (this.value < 0) throw new Error("value cannot be negative");
|
||||
},
|
||||
}, AST_Constant);
|
||||
|
||||
var AST_BigInt = DEFNODE("BigInt", "value", {
|
||||
$documentation: "A BigInt literal",
|
||||
$propdoc: {
|
||||
value: "[string] the numeric representation",
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.value != "string") throw new Error("value must be string");
|
||||
if (this.value[0] == "-") throw new Error("value cannot be negative");
|
||||
},
|
||||
}, AST_Constant);
|
||||
|
||||
var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
|
|
|
|||
|
|
@ -865,13 +865,11 @@ function OutputStream(options) {
|
|||
});
|
||||
|
||||
PARENS(AST_Number, function(output){
|
||||
if (!output.option("galio")) return false;
|
||||
// https://github.com/mishoo/UglifyJS/pull/1009
|
||||
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||
var value = this.getValue();
|
||||
if (value < 0 || /^0/.test(make_num(value))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return p instanceof AST_PropAccess && p.expression === this && /^0/.test(make_num(this.value));
|
||||
});
|
||||
|
||||
PARENS([ AST_Assign, AST_Conditional ], function(output){
|
||||
|
|
|
|||
25
lib/parse.js
25
lib/parse.js
|
|
@ -377,9 +377,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||
};
|
||||
|
||||
function read_while(pred) {
|
||||
var ret = "", ch, i = 0;
|
||||
while ((ch = peek()) && pred(ch, i++))
|
||||
ret += next();
|
||||
var ret = "", ch;
|
||||
while ((ch = peek()) && pred(ch)) ret += next();
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
|
@ -389,7 +388,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||
|
||||
function read_num(prefix) {
|
||||
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
||||
var num = read_while(function(ch, i){
|
||||
var num = read_while(function(ch){
|
||||
var code = ch.charCodeAt(0);
|
||||
switch (code) {
|
||||
case 98: case 66: // bB
|
||||
|
|
@ -399,9 +398,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||
return has_x ? false : (has_x = true);
|
||||
case 101: case 69: // eE
|
||||
return has_x ? true : has_e ? false : (has_e = after_e = true);
|
||||
case 45: // -
|
||||
return after_e || (i == 0 && !prefix);
|
||||
case 43: // +
|
||||
case 43: case 45:
|
||||
return after_e;
|
||||
case (after_e = false, 46): // .
|
||||
return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
|
||||
|
|
@ -413,11 +410,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||
parse_error("Legacy octal literals are not allowed in strict mode");
|
||||
}
|
||||
var valid = parse_js_number(num);
|
||||
if (!isNaN(valid)) {
|
||||
return token("num", valid);
|
||||
} else {
|
||||
parse_error("Invalid syntax: " + num);
|
||||
}
|
||||
if (isNaN(valid)) parse_error("Invalid syntax: " + num);
|
||||
if (has_dot || has_e || peek() != "n") return token("num", valid);
|
||||
return token("bigint", num.toLowerCase() + next());
|
||||
};
|
||||
|
||||
function read_escaped_char(in_string) {
|
||||
|
|
@ -847,7 +842,7 @@ var PRECEDENCE = (function(a, ret){
|
|||
{}
|
||||
);
|
||||
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "bigint", "num", "string", "regexp", "name" ]);
|
||||
|
||||
/* -----[ Parser ]----- */
|
||||
|
||||
|
|
@ -1003,6 +998,7 @@ function parse($TEXT, options) {
|
|||
return dir ? new AST_Directive(stat.body) : stat;
|
||||
case "template_head":
|
||||
case "num":
|
||||
case "bigint":
|
||||
case "regexp":
|
||||
case "operator":
|
||||
case "atom":
|
||||
|
|
@ -1935,6 +1931,9 @@ function parse($TEXT, options) {
|
|||
case "num":
|
||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
case "bigint":
|
||||
ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({
|
||||
start : tok,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ holes_and_undefined: {
|
|||
}
|
||||
}
|
||||
|
||||
constant_join: {
|
||||
constant_join_1: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
|
|
@ -37,7 +37,7 @@ constant_join: {
|
|||
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
|
||||
var c6 = [ 1, 2, null, undefined, "foo", "bar", baz() ].join();
|
||||
var d = [ "foo", 1 + 2 + "bar", "baz" ].join("-");
|
||||
var e = [].join(foo + bar);
|
||||
var e = (foo, bar, "");
|
||||
var f = [].join("");
|
||||
var g = [].join("foo");
|
||||
}
|
||||
|
|
|
|||
46
test/compress/bigint.js
Normal file
46
test/compress/bigint.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
arithmetic: {
|
||||
input: {
|
||||
console.log(((1n + 0x2n) * (0o3n - -4n)) >> (5n - 6n));
|
||||
}
|
||||
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
|
||||
expect_stdout: "42n"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
minus_dot: {
|
||||
input: {
|
||||
console.log(typeof -42n.toString(), typeof (-42n).toString());
|
||||
}
|
||||
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
|
||||
expect_stdout: "number string"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log((0xDEAD_BEEFn).toString(16));
|
||||
}
|
||||
expect: {
|
||||
console.log(0xdeadbeefn.toString(16));
|
||||
}
|
||||
expect_stdout: "deadbeef"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
Number: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(Number(-0xfeed_dead_beef_badn));
|
||||
}
|
||||
expect: {
|
||||
console.log(+("" + -0xfeed_dead_beef_badn));
|
||||
}
|
||||
expect_stdout: "-1148098955808013200"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ issue_269_1: {
|
|||
}
|
||||
expect: {
|
||||
f(
|
||||
x + '', +x, !!x,
|
||||
'' + x, +('' + x), !!x,
|
||||
'', 0, false
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ evaluate_3: {
|
|||
console.log(1 + Number(x) + 2);
|
||||
}
|
||||
expect: {
|
||||
console.log(3 + +x);
|
||||
console.log(+("" + x) + 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user