Skip to content

Commit

Permalink
enhance "functions" (#4791)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Mar 16, 2021
1 parent b872ffe commit b244b4e
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 37 deletions.
29 changes: 14 additions & 15 deletions lib/compress.js
Expand Up @@ -6203,8 +6203,8 @@ merge(Compressor.prototype, {
&& value instanceof AST_LambdaExpression
&& !is_arrow(value)
&& assigned_once(value, sym.references)
&& can_declare_defun()
&& can_rename(value, def.name.name)) {
&& can_declare_defun(value)
&& (old_def = rename_def(value, def.name.name)) !== false) {
AST_Node.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name));
var ctor;
switch (value.CTOR) {
Expand Down Expand Up @@ -6269,27 +6269,26 @@ merge(Compressor.prototype, {
});
}

function can_declare_defun() {
if (compressor.has_directive("use strict")) return parent instanceof AST_Scope;
function can_declare_defun(fn) {
if (compressor.has_directive("use strict") || !(fn instanceof AST_Function)) {
return parent instanceof AST_Scope;
}
return parent instanceof AST_Block
|| parent instanceof AST_For && parent.init === node
|| parent instanceof AST_If;
}

function can_rename(fn, name) {
if (!fn.name) return !fn.variables.get(name);
old_def = fn.name.definition();
if (old_def.orig.length > 1) {
old_def = null;
} else {
if (old_def.assignments > 0) return false;
if (old_def.name == name) return true;
}
function rename_def(fn, name) {
if (!fn.name) return null;
var def = fn.name.definition();
if (def.orig.length > 1) return null;
if (def.assignments > 0) return false;
if (def.name == name) return def;
if (name == "await" && is_async(fn)) return false;
if (name == "yield" && is_generator(fn)) return false;
return !old_def || all(old_def.references, function(ref) {
return all(def.references, function(ref) {
return ref.scope.find_variable(name) === sym;
});
}) && def;
}

function is_catch(node) {
Expand Down
64 changes: 56 additions & 8 deletions test/compress/awaits.js
Expand Up @@ -614,14 +614,14 @@ functions: {
async function b() {
return !!b;
}
var c = async function(c) {
async function c(c) {
return c;
};
}
if (await c(await b(await a()))) {
async function d() {}
async function e() {
return typeof e;
}
var d = async function() {};
var e = async function y() {
return typeof y;
};
var f = async function(f) {
return f;
};
Expand Down Expand Up @@ -672,9 +672,9 @@ functions_use_strict: {
async function b() {
return !!b;
}
var c = async function(c) {
async function c(c) {
return c;
};
}
if (await c(await b(await a()))) {
var d = async function() {};
var e = async function y() {
Expand All @@ -691,6 +691,54 @@ functions_use_strict: {
node_version: ">=8"
}

functions_anonymous: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var await = async function() {
console.log("PASS");
};
await(await);
}
expect: {
async function await() {
console.log("PASS");
}
await();
}
expect_stdout: "PASS"
node_version: ">=8"
}

functions_inner_var: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var await = function a() {
var a;
console.log(a, a);
};
await(await);
}
expect: {
function await() {
var a;
console.log(a, a);
}
await();
}
expect_stdout: "undefined undefined"
node_version: ">=8"
}

issue_4335_1: {
options = {
inline: true,
Expand Down
36 changes: 30 additions & 6 deletions test/compress/functions.js
Expand Up @@ -2751,17 +2751,17 @@ functions: {
function b() {
return !!b;
}
var c = function(c) {
function c(c) {
return c;
};
}
if (c(b(a()))) {
function d() {}
function e() {
return typeof e;
}
var f = function(f) {
function f(f) {
return f;
};
}
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
}
}();
Expand Down Expand Up @@ -2808,9 +2808,9 @@ functions_use_strict: {
function b() {
return !!b;
}
var c = function(c) {
function c(c) {
return c;
};
}
if (c(b(a()))) {
var d = function() {};
var e = function y() {
Expand All @@ -2826,6 +2826,30 @@ functions_use_strict: {
expect_stdout: "a true 42 function function function"
}

functions_inner_var: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = function() {
var a;
console.log(a, a);
};
a(a);
}
expect: {
function a() {
var a;
console.log(a, a);
}
a();
}
expect_stdout: "undefined undefined"
}

issue_2437: {
options = {
collapse_vars: true,
Expand Down
64 changes: 56 additions & 8 deletions test/compress/yields.js
Expand Up @@ -388,14 +388,14 @@ functions: {
function* b() {
return !!b;
}
var c = function*(c) {
function* c(c) {
return c;
};
}
if (yield* c(yield* b(yield* a()))) {
function* d() {}
function* e() {
return typeof e;
}
var d = function*() {};
var e = function* y() {
return typeof y;
};
var f = function*(f) {
return f;
};
Expand Down Expand Up @@ -446,9 +446,9 @@ functions_use_strict: {
function* b() {
return !!b;
}
var c = function*(c) {
function* c(c) {
return c;
};
}
if (yield* c(yield* b(yield* a()))) {
var d = function*() {};
var e = function* y() {
Expand All @@ -465,6 +465,54 @@ functions_use_strict: {
node_version: ">=4"
}

functions_anonymous: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var yield = function*() {
return "PASS";
};
console.log(yield().next(yield).value);
}
expect: {
function* yield() {
return "PASS";
}
console.log(yield().next(yield).value);
}
expect_stdout: "PASS"
node_version: ">=4"
}

functions_inner_var: {
options = {
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var yield = function* a() {
var a;
console.log(a, a);
};
yield().next(yield);
}
expect: {
function* yield() {
var a;
console.log(a, a);
}
yield().next(yield);
}
expect_stdout: "undefined undefined"
node_version: ">=4"
}

negate_iife: {
options = {
negate_iife: true,
Expand Down

0 comments on commit b244b4e

Please sign in to comment.