enable collapse_vars & reduce_vars by default

- fix corner cases in `const` optimisation
- deprecate `/*@const*/`

fixes #1497
This commit is contained in:
alexlamsl 2017-02-21 17:09:09 +08:00
parent 7f8d72d9d3
commit afc3108a9a
6 changed files with 47 additions and 23 deletions

View File

@ -456,8 +456,6 @@ separate file and include it into the build. For example you can have a
```javascript ```javascript
const DEBUG = false; const DEBUG = false;
const PRODUCTION = true; const PRODUCTION = true;
// Alternative for environments that don't support `const`
/** @const */ var STAGING = false;
// etc. // etc.
``` ```
@ -468,7 +466,8 @@ and build your code like this:
UglifyJS will notice the constants and, since they cannot be altered, it UglifyJS will notice the constants and, since they cannot be altered, it
will evaluate references to them to the value itself and drop unreachable 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 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.
<a name="codegen-options"></a> <a name="codegen-options"></a>

View File

@ -66,8 +66,8 @@ function Compressor(options, false_by_default) {
hoist_vars : false, hoist_vars : false,
if_return : !false_by_default, if_return : !false_by_default,
join_vars : !false_by_default, join_vars : !false_by_default,
collapse_vars : false, collapse_vars : !false_by_default,
reduce_vars : false, reduce_vars : !false_by_default,
cascade : !false_by_default, cascade : !false_by_default,
side_effects : !false_by_default, side_effects : !false_by_default,
pure_getters : false, pure_getters : false,
@ -1167,7 +1167,7 @@ merge(Compressor.prototype, {
this._evaluating = true; this._evaluating = true;
try { try {
var d = this.definition(); 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 (compressor.option("unsafe")) {
if (!HOP(d.init, '_evaluated')) { if (!HOP(d.init, '_evaluated')) {
d.init._evaluated = ev(d.init, compressor); d.init._evaluated = ev(d.init, compressor);

View File

@ -97,7 +97,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
var scope = self.parent_scope = null; var scope = self.parent_scope = null;
var labels = new Dictionary(); var labels = new Dictionary();
var defun = null; var defun = null;
var last_var_had_const_pragma = false;
var nesting = 0; var nesting = 0;
var tw = new TreeWalker(function(node, descend){ var tw = new TreeWalker(function(node, descend){
if (options.screw_ie8 && node instanceof AST_Catch) { if (options.screw_ie8 && node instanceof AST_Catch) {
@ -155,13 +154,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// later. // later.
(node.scope = defun.parent_scope).def_function(node); (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 else if (node instanceof AST_SymbolVar
|| node instanceof AST_SymbolConst) { || node instanceof AST_SymbolConst) {
var def = defun.def_variable(node); 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; def.init = tw.parent().value;
} }
else if (node instanceof AST_SymbolCatch) { else if (node instanceof AST_SymbolCatch) {
@ -382,12 +378,6 @@ AST_Symbol.DEFMETHOD("global", function(){
return this.definition().global; 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){ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
return defaults(options, { return defaults(options, {
except : [], except : [],

View File

@ -94,7 +94,8 @@ dead_code_const_declaration: {
loops : true, loops : true,
booleans : true, booleans : true,
conditionals : true, conditionals : true,
evaluate : true evaluate : true,
reduce_vars : true,
}; };
input: { input: {
var unused; var unused;
@ -119,7 +120,8 @@ dead_code_const_annotation: {
loops : true, loops : true,
booleans : true, booleans : true,
conditionals : true, conditionals : true,
evaluate : true evaluate : true,
reduce_vars : true,
}; };
input: { input: {
var unused; var unused;
@ -167,7 +169,8 @@ dead_code_const_annotation_complex_scope: {
loops : true, loops : true,
booleans : true, booleans : true,
conditionals : true, conditionals : true,
evaluate : true evaluate : true,
reduce_vars : true,
}; };
input: { input: {
var unused_var; var unused_var;
@ -201,6 +204,5 @@ dead_code_const_annotation_complex_scope: {
var beef = 'good'; var beef = 'good';
var meat = 'beef'; var meat = 'beef';
var pork = 'bad'; var pork = 'bad';
'good' === pork && console.log('reached, not const');
} }
} }

View File

@ -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;
}
}
}

View File

@ -13,7 +13,8 @@ const_declaration: {
const_pragma: { const_pragma: {
options = { options = {
evaluate: true evaluate: true,
reduce_vars: true,
}; };
input: { input: {
@ -27,7 +28,8 @@ const_pragma: {
// for completeness' sake // for completeness' sake
not_const: { not_const: {
options = { options = {
evaluate: true evaluate: true,
reduce_vars: true,
}; };
input: { input: {