Merge pull request #928 from STRML/constPragma
Mark vars with /** @const */ pragma as consts so they can be eliminated.
This commit is contained in:
@@ -395,6 +395,8 @@ 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.
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -404,8 +406,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 possible downside of this approach is that the build
|
code as usual. The build will contain the `const` declarations if you use
|
||||||
will contain the `const` declarations.
|
them. If you are targeting < ES6 environments, use `/** @const */ var`.
|
||||||
|
|
||||||
<a name="codegen-options"></a>
|
<a name="codegen-options"></a>
|
||||||
## Beautifier options
|
## Beautifier options
|
||||||
|
|||||||
12
lib/scope.js
12
lib/scope.js
@@ -94,6 +94,7 @@ 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) {
|
||||||
@@ -151,10 +152,13 @@ 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;
|
def.constant = node instanceof AST_SymbolConst || last_var_had_const_pragma;
|
||||||
def.init = tw.parent().value;
|
def.init = tw.parent().value;
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
@@ -357,6 +361,12 @@ 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 : [],
|
||||||
|
|||||||
@@ -87,3 +87,120 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
var moo;
|
var moo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dead_code_const_declaration: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
const CONST_FOO = false;
|
||||||
|
if (CONST_FOO) {
|
||||||
|
console.log("unreachable");
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
const CONST_FOO = !1;
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
/** @const */ var CONST_FOO_ANN = false;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("unreachable");
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation_regex: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
// @constraint this shouldn't be a constant
|
||||||
|
var CONST_FOO_ANN = false;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("reachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
CONST_FOO_ANN && console.log('reachable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation_complex_scope: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused_var;
|
||||||
|
/** @const */ var test = 'test';
|
||||||
|
// @const
|
||||||
|
var CONST_FOO_ANN = false;
|
||||||
|
var unused_var_2;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("unreachable");
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
if (test === 'test') {
|
||||||
|
var beef = 'good';
|
||||||
|
/** @const */ var meat = 'beef';
|
||||||
|
var pork = 'bad';
|
||||||
|
if (meat === 'pork') {
|
||||||
|
console.log('also unreachable');
|
||||||
|
} else if (pork === 'good') {
|
||||||
|
console.log('reached, not const');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused_var;
|
||||||
|
var test = 'test';
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
var unused_var_2;
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
var beef = 'good';
|
||||||
|
var meat = 'beef';
|
||||||
|
var pork = 'bad';
|
||||||
|
'good' === pork && console.log('reached, not const');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user