@@ -59,7 +59,7 @@ function Compressor(options, false_by_default) {
|
|||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
evaluate : !false_by_default,
|
evaluate : !false_by_default,
|
||||||
expression : false,
|
expression : false,
|
||||||
global_defs : {},
|
global_defs : false,
|
||||||
hoist_funs : false,
|
hoist_funs : false,
|
||||||
hoist_props : !false_by_default,
|
hoist_props : !false_by_default,
|
||||||
hoist_vars : false,
|
hoist_vars : false,
|
||||||
@@ -149,6 +149,7 @@ merge(Compressor.prototype, {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
compress: function(node) {
|
compress: function(node) {
|
||||||
|
node = node.resolve_defines(this);
|
||||||
if (this.option("expression")) {
|
if (this.option("expression")) {
|
||||||
node.process_expression(true);
|
node.process_expression(true);
|
||||||
}
|
}
|
||||||
@@ -2410,22 +2411,6 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(function(def) {
|
(function(def) {
|
||||||
AST_Node.DEFMETHOD("resolve_defines", function(compressor) {
|
|
||||||
if (!compressor.option("global_defs")) return;
|
|
||||||
var def = this._find_defs(compressor, "");
|
|
||||||
if (def) {
|
|
||||||
var node, parent = this, level = 0;
|
|
||||||
do {
|
|
||||||
node = parent;
|
|
||||||
parent = compressor.parent(level++);
|
|
||||||
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
|
||||||
if (is_lhs(node, parent)) {
|
|
||||||
compressor.warn('global_defs ' + this.print_to_string() + ' redefined [{file}:{line},{col}]', this.start);
|
|
||||||
} else {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function to_node(value, orig) {
|
function to_node(value, orig) {
|
||||||
if (value instanceof AST_Node) return make_node(value.CTOR, orig, value);
|
if (value instanceof AST_Node) return make_node(value.CTOR, orig, value);
|
||||||
if (Array.isArray(value)) return make_node(AST_Array, orig, {
|
if (Array.isArray(value)) return make_node(AST_Array, orig, {
|
||||||
@@ -2447,25 +2432,43 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return make_node_from_constant(value, orig);
|
return make_node_from_constant(value, orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function warn(compressor, node) {
|
||||||
|
compressor.warn("global_defs " + node.print_to_string() + " redefined [{file}:{line},{col}]", node.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
|
||||||
|
if (!compressor.option("global_defs")) return this;
|
||||||
|
this.figure_out_scope({ ie8: compressor.option("ie8") });
|
||||||
|
return this.transform(new TreeTransformer(function(node) {
|
||||||
|
var def = node._find_defs(compressor, "");
|
||||||
|
if (!def) return;
|
||||||
|
var level = 0, child = node, parent;
|
||||||
|
while (parent = this.parent(level++)) {
|
||||||
|
if (!(parent instanceof AST_PropAccess)) break;
|
||||||
|
if (parent.expression !== child) break;
|
||||||
|
child = parent;
|
||||||
|
}
|
||||||
|
if (is_lhs(child, parent)) {
|
||||||
|
warn(compressor, node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}));
|
||||||
|
});
|
||||||
def(AST_Node, noop);
|
def(AST_Node, noop);
|
||||||
def(AST_Dot, function(compressor, suffix) {
|
def(AST_Dot, function(compressor, suffix) {
|
||||||
return this.expression._find_defs(compressor, "." + this.property + suffix);
|
return this.expression._find_defs(compressor, "." + this.property + suffix);
|
||||||
});
|
});
|
||||||
|
def(AST_SymbolDeclaration, function(compressor) {
|
||||||
|
if (!this.global()) return;
|
||||||
|
if (HOP(compressor.option("global_defs"), this.name)) warn(compressor, this);
|
||||||
|
});
|
||||||
def(AST_SymbolRef, function(compressor, suffix) {
|
def(AST_SymbolRef, function(compressor, suffix) {
|
||||||
if (!this.global()) return;
|
if (!this.global()) return;
|
||||||
var name;
|
|
||||||
var defines = compressor.option("global_defs");
|
var defines = compressor.option("global_defs");
|
||||||
if (defines && HOP(defines, (name = this.name + suffix))) {
|
var name = this.name + suffix;
|
||||||
var node = to_node(defines[name], this);
|
if (HOP(defines, name)) return to_node(defines[name], this);
|
||||||
var top = compressor.find_parent(AST_Toplevel);
|
|
||||||
node.walk(new TreeWalker(function(node) {
|
|
||||||
if (node instanceof AST_SymbolRef) {
|
|
||||||
node.scope = top;
|
|
||||||
node.thedef = top.def_global(node);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})(function(node, func) {
|
})(function(node, func) {
|
||||||
node.DEFMETHOD("_find_defs", func);
|
node.DEFMETHOD("_find_defs", func);
|
||||||
@@ -5718,10 +5721,6 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OPT(AST_SymbolRef, function(self, compressor) {
|
OPT(AST_SymbolRef, function(self, compressor) {
|
||||||
var def = self.resolve_defines(compressor);
|
|
||||||
if (def) {
|
|
||||||
return def.optimize(compressor);
|
|
||||||
}
|
|
||||||
if (!compressor.option("ie8")
|
if (!compressor.option("ie8")
|
||||||
&& is_undeclared_ref(self)
|
&& is_undeclared_ref(self)
|
||||||
// testing against `self.scope.uses_with` is an optimization
|
// testing against `self.scope.uses_with` is an optimization
|
||||||
@@ -6405,10 +6404,6 @@ merge(Compressor.prototype, {
|
|||||||
col: self.start.col
|
col: self.start.col
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var def = self.resolve_defines(compressor);
|
|
||||||
if (def) {
|
|
||||||
return def.optimize(compressor);
|
|
||||||
}
|
|
||||||
if (is_lhs(self, compressor.parent())) return self;
|
if (is_lhs(self, compressor.parent())) return self;
|
||||||
if (compressor.option("unsafe_proto")
|
if (compressor.option("unsafe_proto")
|
||||||
&& self.expression instanceof AST_Dot
|
&& self.expression instanceof AST_Dot
|
||||||
@@ -6464,14 +6459,6 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_VarDef, function(self, compressor) {
|
|
||||||
var defines = compressor.option("global_defs");
|
|
||||||
if (defines && HOP(defines, self.name.name)) {
|
|
||||||
compressor.warn('global_defs ' + self.name.name + ' redefined [{file}:{line},{col}]', self.start);
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
});
|
|
||||||
})(function(node, optimizer) {
|
})(function(node, optimizer) {
|
||||||
node.DEFMETHOD("optimize", function(compressor) {
|
node.DEFMETHOD("optimize", function(compressor) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|||||||
@@ -1161,7 +1161,7 @@ function OutputStream(options) {
|
|||||||
def.print(output);
|
def.print(output);
|
||||||
});
|
});
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon();
|
if (p && p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon();
|
||||||
});
|
});
|
||||||
|
|
||||||
function parenthesize_for_noin(node, output, noin) {
|
function parenthesize_for_noin(node, output, noin) {
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ mixed: {
|
|||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
||||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:5,22]",
|
|
||||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -197,3 +196,23 @@ issue_2167: {
|
|||||||
doWork();
|
doWork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3217: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
global_defs: {
|
||||||
|
"@o": "{fn:function(){var a=42;console.log(a)}}",
|
||||||
|
},
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
o.fn();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user