enable collapse_vars & reduce_vars by default
- fix corner cases in `const` optimisation - deprecate `/*@const*/` fixes #1497 closes #1498
This commit is contained in:
@@ -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.
|
||||
|
||||
<a name="codegen-options"></a>
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
12
lib/scope.js
12
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 : [],
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,6 +602,7 @@ unsafe_prototype_function: {
|
||||
call_args: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
const a = 1;
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user