drop_debugger : !false_by_default,
evaluate : !false_by_default,
expression : false,
- global_defs : {},
+ global_defs : false,
hoist_funs : false,
hoist_props : !false_by_default,
hoist_vars : false,
return false;
},
compress: function(node) {
+ node = node.resolve_defines(this);
if (this.option("expression")) {
node.process_expression(true);
}
}
(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) {
if (value instanceof AST_Node) return make_node(value.CTOR, orig, value);
if (Array.isArray(value)) return make_node(AST_Array, 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_Dot, function(compressor, 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) {
if (!this.global()) return;
- var name;
var defines = compressor.option("global_defs");
- if (defines && HOP(defines, (name = this.name + suffix))) {
- var node = 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;
- }
+ var name = this.name + suffix;
+ if (HOP(defines, name)) return to_node(defines[name], this);
});
})(function(node, func) {
node.DEFMETHOD("_find_defs", func);
}
OPT(AST_SymbolRef, function(self, compressor) {
- var def = self.resolve_defines(compressor);
- if (def) {
- return def.optimize(compressor);
- }
if (!compressor.option("ie8")
&& is_undeclared_ref(self)
// testing against `self.scope.uses_with` is an optimization
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 (compressor.option("unsafe_proto")
&& self.expression instanceof AST_Dot
}
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) {
node.DEFMETHOD("optimize", function(compressor) {
var self = this;