From afc3108a9a966ead3a514644c0c6b0a9166cd12e Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Tue, 21 Feb 2017 17:09:09 +0800 Subject: [PATCH] enable `collapse_vars` & `reduce_vars` by default - fix corner cases in `const` optimisation - deprecate `/*@const*/` fixes #1497 --- README.md | 5 ++--- lib/compress.js | 6 +++--- lib/scope.js | 12 +----------- test/compress/dead-code.js | 10 ++++++---- test/compress/drop-unused.js | 31 +++++++++++++++++++++++++++++++ test/compress/issue-1041.js | 6 ++++-- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index a8b55843..5b8b649a 100644 --- a/README.md +++ b/README.md @@ -456,8 +456,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. ``` @@ -468,7 +466,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 4e45df92..1af24e96 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -66,8 +66,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, @@ -1167,7 +1167,7 @@ merge(Compressor.prototype, { this._evaluating = true; try { var d = this.definition(); - if (d && (d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) { + if (d && compressor.option("reduce_vars") && !d.modified && d.init) { if (compressor.option("unsafe")) { if (!HOP(d.init, '_evaluated')) { d.init._evaluated = ev(d.init, compressor); diff --git a/lib/scope.js b/lib/scope.js index 55d1eff1..3d5d2c63 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 nesting = 0; var tw = new TreeWalker(function(node, descend){ if (options.screw_ie8 && node instanceof AST_Catch) { @@ -155,13 +154,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) { @@ -382,12 +378,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/dead-code.js b/test/compress/dead-code.js index fa4b37d6..c0419efe 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 035a428e..a2a63401 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -177,3 +177,34 @@ keep_fnames: { } } } + +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/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: {