aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-11-04 00:31:37 +0800
committerGitHub <noreply@github.com>2017-11-04 00:31:37 +0800
commitc8b6f4733d35db48b5b7e2373264db0d99eb299f (patch)
treef609933db48323267cc3709cb63732dd6a2df895 /lib/compress.js
parenta48f87abf2fb09cc8296444eb613021ef66492c3 (diff)
downloadtracifyjs-c8b6f4733d35db48b5b7e2373264db0d99eb299f.tar.gz
tracifyjs-c8b6f4733d35db48b5b7e2373264db0d99eb299f.zip
reduce `this` within functions (#2421)
- only replace same-scope usages - augment `test/ufuzz.js` to test for `this` fixes #2420
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js75
1 files changed, 44 insertions, 31 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 99ab7b7a..f09f2b9b 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -285,7 +285,7 @@ merge(Compressor.prototype, {
self.transform(tt);
});
- AST_Node.DEFMETHOD("reset_opt_flags", function(compressor) {
+ AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
var reduce_vars = compressor.option("reduce_vars");
var unused = compressor.option("unused");
// Stack of look-up tables to keep track of whether a `SymbolDef` has been
@@ -564,7 +564,10 @@ merge(Compressor.prototype, {
}
function is_immutable(value) {
- return value && (value.is_constant() || value instanceof AST_Lambda);
+ if (!value) return false;
+ return value.is_constant()
+ || value instanceof AST_Lambda
+ || value instanceof AST_This;
}
function read_property(obj, key) {
@@ -4211,39 +4214,49 @@ merge(Compressor.prototype, {
var value = fixed.optimize(compressor);
return value === fixed ? fixed.clone(true) : value;
}
- if (compressor.option("evaluate") && fixed) {
- if (d.should_replace === undefined) {
- var init = fixed.evaluate(compressor);
- if (init !== fixed && (compressor.option("unsafe_regexp") || !(init instanceof RegExp))) {
- init = make_node_from_constant(init, fixed);
- var value_length = init.optimize(compressor).print_to_string().length;
- var fn;
- if (has_symbol_ref(fixed)) {
- fn = function() {
- var result = init.optimize(compressor);
- return result === init ? result.clone(true) : result;
- };
- } else {
- value_length = Math.min(value_length, fixed.print_to_string().length);
- fn = function() {
- var result = best_of_expression(init.optimize(compressor), fixed);
- return result === init || result === fixed ? result.clone(true) : result;
- };
- }
- var name_length = d.name.length;
- var overhead = 0;
- if (compressor.option("unused") && !compressor.exposed(d)) {
- overhead = (name_length + 2 + value_length) / d.references.length;
- }
- d.should_replace = value_length <= name_length + overhead ? fn : false;
- } else {
- d.should_replace = false;
+ if (fixed && d.should_replace === undefined) {
+ var init;
+ if (fixed instanceof AST_This) {
+ if (!(d.orig[0] instanceof AST_SymbolFunarg)
+ && all(d.references, function(ref) {
+ return d.scope === ref.scope;
+ })) {
+ init = fixed;
+ }
+ } else {
+ var ev = fixed.evaluate(compressor);
+ if (ev !== fixed && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))) {
+ init = make_node_from_constant(ev, fixed);
}
}
- if (d.should_replace) {
- return d.should_replace();
+ if (init) {
+ var value_length = init.optimize(compressor).print_to_string().length;
+ var fn;
+ if (has_symbol_ref(fixed)) {
+ fn = function() {
+ var result = init.optimize(compressor);
+ return result === init ? result.clone(true) : result;
+ };
+ } else {
+ value_length = Math.min(value_length, fixed.print_to_string().length);
+ fn = function() {
+ var result = best_of_expression(init.optimize(compressor), fixed);
+ return result === init || result === fixed ? result.clone(true) : result;
+ };
+ }
+ var name_length = d.name.length;
+ var overhead = 0;
+ if (compressor.option("unused") && !compressor.exposed(d)) {
+ overhead = (name_length + 2 + value_length) / d.references.length;
+ }
+ d.should_replace = value_length <= name_length + overhead ? fn : false;
+ } else {
+ d.should_replace = false;
}
}
+ if (d.should_replace) {
+ return d.should_replace();
+ }
}
return self;