parent
dea0cc0662
commit
000620be59
|
|
@ -90,6 +90,8 @@ function Compressor(options, false_by_default) {
|
||||||
unsafe_regexp : false,
|
unsafe_regexp : false,
|
||||||
unsafe_undefined: false,
|
unsafe_undefined: false,
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
|
// TODO Is "void" a good name? "void_to_var"?
|
||||||
|
void : false,
|
||||||
warnings : false,
|
warnings : false,
|
||||||
}, true);
|
}, true);
|
||||||
var global_defs = this.options["global_defs"];
|
var global_defs = this.options["global_defs"];
|
||||||
|
|
@ -199,6 +201,13 @@ merge(Compressor.prototype, {
|
||||||
if (this.option("expression")) {
|
if (this.option("expression")) {
|
||||||
node.process_expression(false);
|
node.process_expression(false);
|
||||||
}
|
}
|
||||||
|
if (this.option("void")) {
|
||||||
|
try {
|
||||||
|
node.process_void();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
info: function() {
|
info: function() {
|
||||||
|
|
@ -315,6 +324,75 @@ merge(Compressor.prototype, {
|
||||||
self.transform(tt);
|
self.transform(tt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("process_void", function (compressor) {
|
||||||
|
var lambdas_with_var = [];
|
||||||
|
var tw = new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Var) {
|
||||||
|
// TODO Find parent efficiently
|
||||||
|
// TODO Should AST_Scope be used instead?
|
||||||
|
var lambda = tw.find_parent(AST_Lambda);
|
||||||
|
if (lambda && !lambda._first_var) {
|
||||||
|
lambda._first_var = node;
|
||||||
|
lambdas_with_var.push(lambda);
|
||||||
|
}
|
||||||
|
} else if (node instanceof AST_UnaryPrefix
|
||||||
|
&& node.operator == "void"
|
||||||
|
&& node.expression instanceof AST_Number) {
|
||||||
|
// TODO Find parent efficiently
|
||||||
|
// TODO Should AST_Scope be used instead?
|
||||||
|
var lambda = tw.find_parent(AST_Lambda);
|
||||||
|
if (lambda) {
|
||||||
|
if (!lambda._void_uses) lambda._void_uses = [];
|
||||||
|
// TODO Simpler way?
|
||||||
|
node._parent = tw.parent();
|
||||||
|
lambda._void_uses.push(node);
|
||||||
|
}
|
||||||
|
} else if (node instanceof AST_Catch
|
||||||
|
&& node.argname.name.indexOf("undefined") == 0) {
|
||||||
|
// TODO Is there a cleaner way to do this?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.walk(tw);
|
||||||
|
|
||||||
|
// TODO Is there a better way to replace a node?
|
||||||
|
var replacer = new TreeTransformer(function(node) {
|
||||||
|
if (node._replacement) {
|
||||||
|
return node._replacement;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
lambdas_with_var.forEach(function(lambda) {
|
||||||
|
if (lambda._processed_void || !lambda._void_uses) return;
|
||||||
|
|
||||||
|
// TODO This is similar to make_sym() below. Should they be combined?
|
||||||
|
var new_var = make_node(AST_SymbolVar, null, {
|
||||||
|
name: lambda.make_var_name("undefined"),
|
||||||
|
scope: lambda,
|
||||||
|
});
|
||||||
|
|
||||||
|
var def = lambda.def_variable(new_var);
|
||||||
|
lambda.enclosed.push(def);
|
||||||
|
|
||||||
|
var new_var_def = make_node(AST_VarDef, lambda._first_var, {
|
||||||
|
name: new_var,
|
||||||
|
value: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
lambda._first_var.definitions.push(new_var_def);
|
||||||
|
|
||||||
|
|
||||||
|
lambda._void_uses.forEach(function(void_use) {
|
||||||
|
// TODO Is there a better way to replace a node?
|
||||||
|
void_use._replacement = make_node(AST_SymbolRef, void_use, new_var);
|
||||||
|
void_use._parent.transform(replacer);
|
||||||
|
});
|
||||||
|
|
||||||
|
lambda._processed_void = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
(function(def){
|
(function(def){
|
||||||
def(AST_Node, noop);
|
def(AST_Node, noop);
|
||||||
|
|
||||||
|
|
|
||||||
125
test/compress/void.js
Normal file
125
test/compress/void.js
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
void_1: {
|
||||||
|
options = {
|
||||||
|
void: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
x = void 0;
|
||||||
|
if (void 0 === b)
|
||||||
|
c = void 0;
|
||||||
|
|
||||||
|
function f1() {
|
||||||
|
var a = 1;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f2(undefined) {
|
||||||
|
var a = 2;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f3() {
|
||||||
|
var undefined = 3;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f4() {
|
||||||
|
console.log(void 0);
|
||||||
|
for (var a = 4;;);
|
||||||
|
var b = 4;
|
||||||
|
|
||||||
|
function f5() {
|
||||||
|
var c = 5;
|
||||||
|
var d = 5;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f6() {
|
||||||
|
try {
|
||||||
|
var a = 6;
|
||||||
|
console.log(void 0);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
x = void 0;
|
||||||
|
if (void 0 === b)
|
||||||
|
c = void 0;
|
||||||
|
|
||||||
|
function f1() {
|
||||||
|
var a = 1, undefined;
|
||||||
|
console.log(undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
function f2(undefined) {
|
||||||
|
var a = 2, undefined$0;
|
||||||
|
console.log(undefined$0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function f3() {
|
||||||
|
var undefined = 3, undefined$0;
|
||||||
|
console.log(undefined$0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function f4() {
|
||||||
|
console.log(undefined);
|
||||||
|
for (var a = 4, undefined;;);
|
||||||
|
var b = 4;
|
||||||
|
|
||||||
|
function f5() {
|
||||||
|
var c = 5, undefined;
|
||||||
|
var d = 5;
|
||||||
|
console.log(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f6() {
|
||||||
|
try {
|
||||||
|
var a = 6, undefined;
|
||||||
|
console.log(undefined)
|
||||||
|
} catch (e) {
|
||||||
|
console.log(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void_2: {
|
||||||
|
options = {
|
||||||
|
void: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f();
|
||||||
|
function f() {
|
||||||
|
var a = 1;
|
||||||
|
console.log(void 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (undefined) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
f();
|
||||||
|
function f() {
|
||||||
|
var a = 1, undefined;
|
||||||
|
console.log(undefined);
|
||||||
|
try {
|
||||||
|
throw "FAIL"
|
||||||
|
} catch (undefined) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user