From: alexlamsl Date: Thu, 23 Feb 2017 17:46:57 +0000 (+0800) Subject: enable `collapse_vars` & `reduce_vars` by default X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=4e49302916fe395f5c63992aa28c33392208fb27;p=UglifyJS.git enable `collapse_vars` & `reduce_vars` by default - fix corner cases in `const` optimisation - deprecate `/*@const*/` fixes #1497 closes #1498 --- diff --git a/README.md b/README.md index 06ffa0e8..1d0244ee 100644 --- a/README.md +++ b/README.md @@ -469,8 +469,6 @@ separate file and include it into the build. For example you can have a ```javascript const DEBUG = false; const PRODUCTION = true; -// Alternative for environments that don't support `const` -/** @const */ var STAGING = false; // etc. ``` @@ -481,7 +479,8 @@ and build your code like this: UglifyJS will notice the constants and, since they cannot be altered, it will evaluate references to them to the value itself and drop unreachable code as usual. The build will contain the `const` declarations if you use -them. If you are targeting < ES6 environments, use `/** @const */ var`. +them. If you are targeting < ES6 environments which does not support `const`, +using `var` with `reduce_vars` (enabled by default) should suffice. diff --git a/lib/compress.js b/lib/compress.js index 95e9c1b3..2bc1c5a5 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -69,8 +69,8 @@ function Compressor(options, false_by_default) { hoist_vars : false, if_return : !false_by_default, join_vars : !false_by_default, - collapse_vars : false, - reduce_vars : false, + collapse_vars : !false_by_default, + reduce_vars : !false_by_default, cascade : !false_by_default, side_effects : !false_by_default, pure_getters : false, @@ -1252,7 +1252,7 @@ merge(Compressor.prototype, { this._evaluating = true; try { var d = this.definition(); - if ((d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) { + if (compressor.option("reduce_vars") && !d.modified && d.init) { if (compressor.option("unsafe")) { if (!HOP(d.init, '_evaluated')) { d.init._evaluated = ev(d.init, compressor); @@ -3025,9 +3025,11 @@ merge(Compressor.prototype, { return make_node(AST_Infinity, self).transform(compressor); } } - if (compressor.option("evaluate") && !isLHS(self, compressor.parent())) { + if (compressor.option("evaluate") + && compressor.option("reduce_vars") + && !isLHS(self, compressor.parent())) { var d = self.definition(); - if (d && d.constant && d.init && d.init.is_constant(compressor)) { + if (d.constant && !d.modified && d.init && d.init.is_constant(compressor)) { var original_as_string = self.print_to_string(); var const_node = make_node_from_constant(compressor, d.init.constant_value(compressor), self); var const_node_as_string = const_node.print_to_string(); diff --git a/lib/scope.js b/lib/scope.js index b0d92d7d..29e4103a 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -97,7 +97,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ var scope = self.parent_scope = null; var labels = new Dictionary(); var defun = null; - var last_var_had_const_pragma = false; var tw = new TreeWalker(function(node, descend){ if (options.screw_ie8 && node instanceof AST_Catch) { var save_scope = scope; @@ -154,13 +153,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ // later. (node.scope = defun.parent_scope).def_function(node); } - else if (node instanceof AST_Var) { - last_var_had_const_pragma = node.has_const_pragma(); - } else if (node instanceof AST_SymbolVar || node instanceof AST_SymbolConst) { var def = defun.def_variable(node); - def.constant = node instanceof AST_SymbolConst || last_var_had_const_pragma; + def.constant = node instanceof AST_SymbolConst; def.init = tw.parent().value; } else if (node instanceof AST_SymbolCatch) { @@ -369,12 +365,6 @@ AST_Symbol.DEFMETHOD("global", function(){ return this.definition().global; }); -AST_Var.DEFMETHOD("has_const_pragma", function() { - var comments_before = this.start && this.start.comments_before; - var lastComment = comments_before && comments_before[comments_before.length - 1]; - return lastComment && /@const\b/.test(lastComment.value); -}); - AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){ return defaults(options, { except : [], diff --git a/test/compress/const.js b/test/compress/const.js index dd175fcc..f1f13f49 100644 --- a/test/compress/const.js +++ b/test/compress/const.js @@ -12,6 +12,7 @@ issue_1191: { join_vars : true, sequences : false, collapse_vars : false, + reduce_vars : true, } input: { function foo(rot) { @@ -43,6 +44,7 @@ issue_1194: { join_vars : true, sequences : false, collapse_vars : false, + reduce_vars : true, } input: { function f1() {const a = "X"; return a + a;} @@ -70,6 +72,7 @@ issue_1396: { join_vars : true, sequences : false, collapse_vars : false, + reduce_vars : true, } input: { function foo(a) { @@ -140,6 +143,7 @@ regexp_literal_not_const: { join_vars : true, sequences : false, collapse_vars : false, + reduce_vars : true, } input: { (function(){ diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js index c83f2040..2596e80e 100644 --- a/test/compress/dead-code.js +++ b/test/compress/dead-code.js @@ -94,7 +94,8 @@ dead_code_const_declaration: { loops : true, booleans : true, conditionals : true, - evaluate : true + evaluate : true, + reduce_vars : true, }; input: { var unused; @@ -119,7 +120,8 @@ dead_code_const_annotation: { loops : true, booleans : true, conditionals : true, - evaluate : true + evaluate : true, + reduce_vars : true, }; input: { var unused; @@ -167,7 +169,8 @@ dead_code_const_annotation_complex_scope: { loops : true, booleans : true, conditionals : true, - evaluate : true + evaluate : true, + reduce_vars : true, }; input: { var unused_var; @@ -201,6 +204,5 @@ dead_code_const_annotation_complex_scope: { var beef = 'good'; var meat = 'beef'; var pork = 'bad'; - 'good' === pork && console.log('reached, not const'); } } diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index f5a88f21..c1ca1b55 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -648,3 +648,34 @@ drop_value: { foo(), bar(); } } + +const_assign: { + options = { + evaluate: true, + reduce_vars: true, + unused: true, + } + input: { + function f() { + const b = 2; + return 1 + b; + } + + function g() { + const b = 2; + b = 3; + return 1 + b; + } + } + expect: { + function f() { + return 3; + } + + function g() { + const b = 2; + b = 3; + return 1 + b; + } + } +} diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index f88bc538..ae5e58d6 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -602,6 +602,7 @@ unsafe_prototype_function: { call_args: { options = { evaluate: true, + reduce_vars: true, } input: { const a = 1; diff --git a/test/compress/issue-1041.js b/test/compress/issue-1041.js index 9dd176fd..cdbc22cc 100644 --- a/test/compress/issue-1041.js +++ b/test/compress/issue-1041.js @@ -13,7 +13,8 @@ const_declaration: { const_pragma: { options = { - evaluate: true + evaluate: true, + reduce_vars: true, }; input: { @@ -27,7 +28,8 @@ const_pragma: { // for completeness' sake not_const: { options = { - evaluate: true + evaluate: true, + reduce_vars: true, }; input: {