upgrade AST<->ESTree translation (#4870)

fixes #968
This commit is contained in:
Alex Lam S.L 2021-04-26 04:23:52 +08:00 committed by GitHub
parent 80efaa2f33
commit 324587f769
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 801 additions and 177 deletions

View File

@ -235,7 +235,7 @@ if (options.mangle && options.mangle.properties) {
}); });
} }
} }
if (output == "ast") options.output = { if (output == "ast" || output == "spidermonkey") options.output = {
ast: true, ast: true,
code: false, code: false,
}; };
@ -313,9 +313,11 @@ function run() {
if (options.parse.acorn) { if (options.parse.acorn) {
files = convert_ast(function(toplevel, name) { files = convert_ast(function(toplevel, name) {
return require("acorn").parse(files[name], { return require("acorn").parse(files[name], {
ecmaVersion: "latest",
locations: true, locations: true,
program: toplevel, program: toplevel,
sourceFile: name sourceFile: name,
sourceType: "module",
}); });
}); });
} else if (options.parse.spidermonkey) { } else if (options.parse.spidermonkey) {
@ -409,14 +411,7 @@ function run() {
return value; return value;
}, 2)); }, 2));
} else if (output == "spidermonkey") { } else if (output == "spidermonkey") {
print(JSON.stringify(UglifyJS.minify(result.code, { print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2));
compress: false,
mangle: false,
output: {
ast: true,
code: false
},
}).ast.to_mozilla_ast(), null, 2));
} else if (output) { } else if (output) {
fs.writeFileSync(output, result.code); fs.writeFileSync(output, result.code);
if (result.map) fs.writeFileSync(output + ".map", result.map); if (result.map) fs.writeFileSync(output + ".map", result.map);

View File

@ -6562,6 +6562,10 @@ merge(Compressor.prototype, {
} }
return insert_statements(body, node, in_list); return insert_statements(body, node, in_list);
} }
if (node instanceof AST_Import) {
if (node.properties && node.properties == 0) node.properties = null;
return node;
}
if (node instanceof AST_Sequence) { if (node instanceof AST_Sequence) {
if (node.expressions.length > 1) return; if (node.expressions.length > 1) return;
return maintain_this_binding(compressor, tt.parent(), node, node.expressions[0]); return maintain_this_binding(compressor, tt.parent(), node, node.expressions[0]);

File diff suppressed because it is too large Load Diff

View File

@ -2526,7 +2526,7 @@ function parse($TEXT, options) {
while (!is("eof")) while (!is("eof"))
body.push(statement()); body.push(statement());
S.input.pop_directives_stack(); S.input.pop_directives_stack();
var end = prev(); var end = prev() || start;
var toplevel = options.toplevel; var toplevel = options.toplevel;
if (toplevel) { if (toplevel) {
toplevel.body = toplevel.body.concat(body); toplevel.body = toplevel.body.concat(body);

View File

@ -23,7 +23,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"acorn": "~7.1.0", "acorn": "~8.2.1",
"semver": "~6.3.0" "semver": "~6.3.0"
}, },
"scripts": { "scripts": {

View File

@ -11,7 +11,7 @@ function try_beautify(code) {
mangle: false, mangle: false,
output: { output: {
beautify: true, beautify: true,
braces: true braces: true,
} }
}); });
if (beautified.error) { if (beautified.error) {
@ -35,12 +35,18 @@ function validate(ast) {
return UglifyJS.minify(ast, { return UglifyJS.minify(ast, {
compress: false, compress: false,
mangle: false, mangle: false,
validate: true,
}); });
} }
function fuzzy(code) {
return code.replace(/\bimport\s*\{\s*\}\s*from\s*(['"])/g, "import$1")
.replace(/\b(import\b.*?)\s*,\s*\{\s*\}\s*(from\s*['"])/g, "$1 $2");
}
function test(original, estree, description) { function test(original, estree, description) {
var transformed = validate(UglifyJS.AST_Node.from_mozilla_ast(estree)); var transformed = validate(UglifyJS.AST_Node.from_mozilla_ast(estree));
if (transformed.error || original !== transformed.code) { if (transformed.error || original !== transformed.code && fuzzy(original) !== fuzzy(transformed.code)) {
console.log("//============================================================="); console.log("//=============================================================");
console.log("// !!!!!! Failed... round", round); console.log("// !!!!!! Failed... round", round);
console.log("// original code"); console.log("// original code");
@ -72,19 +78,36 @@ for (var round = 1; round <= num_iterations; round++) {
compress: false, compress: false,
mangle: false, mangle: false,
output: { output: {
ast: true ast: true,
} },
}); });
var ok = test(uglified.code, uglified.ast.to_mozilla_ast(), "AST_Node.to_mozilla_ast()"); var ok = true;
try { try {
ok = test(uglified.code, acorn.parse(input), "acorn.parse()") && ok; var estree = uglified.ast.to_mozilla_ast();
} catch (e) { } catch (e) {
ok = false;
console.log("//============================================================="); console.log("//=============================================================");
console.log("// acorn parser failed... round", round); console.log("// AST_Node.to_mozilla_ast() failed... round", round);
console.log(e); console.log(e);
console.log("// original code"); console.log("// original code");
console.log(input); console.log(input);
} }
if (ok) ok = test(uglified.code, estree, "AST_Node.to_mozilla_ast()");
if (ok) try {
ok = test(uglified.code, acorn.parse(input, {
ecmaVersion: "latest",
locations: true,
sourceType: "module",
}), "acorn.parse()");
} catch (e) {
if (ufuzz.verbose) {
console.log("//=============================================================");
console.log("// acorn parser failed... round", round);
console.log(e);
console.log("// original code");
console.log(input);
}
}
if (!ok) process.exit(1); if (!ok) process.exit(1);
}); });
} }

View File

@ -2045,6 +2045,7 @@ function createVarName(maybe, dontStore) {
if (require.main !== module) { if (require.main !== module) {
exports.createTopLevelCode = createTopLevelCode; exports.createTopLevelCode = createTopLevelCode;
exports.num_iterations = num_iterations; exports.num_iterations = num_iterations;
exports.verbose = verbose;
return; return;
} }

View File

@ -56,6 +56,9 @@ if (+process.env["UGLIFY_BUG_REPORT"]) exports.minify = function(files, options)
function describe_ast() { function describe_ast() {
var out = OutputStream({ beautify: true }); var out = OutputStream({ beautify: true });
doitem(AST_Node);
return out.get() + "\n";
function doitem(ctor) { function doitem(ctor) {
out.print("AST_" + ctor.TYPE); out.print("AST_" + ctor.TYPE);
var props = ctor.SELF_PROPS.filter(function(prop) { var props = ctor.SELF_PROPS.filter(function(prop) {
@ -86,9 +89,7 @@ function describe_ast() {
}); });
}); });
} }
}; }
doitem(AST_Node);
return out + "\n";
} }
function infer_options(options) { function infer_options(options) {