Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6920e898d1 | ||
|
|
dd71639264 | ||
|
|
2dcc552ce0 | ||
|
|
55387e8fd0 | ||
|
|
7e3e9da860 | ||
|
|
00f509405b | ||
|
|
aceb0af36b | ||
|
|
4f0953f7e9 | ||
|
|
182a47bfb1 |
@@ -134,11 +134,10 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
|||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value scope quote", {
|
var AST_Directive = DEFNODE("Directive", "value quote", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";",
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
scope: "[AST_Scope/S] The scope that this directive affects",
|
|
||||||
quote: "[string] the original quote character"
|
quote: "[string] the original quote character"
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -299,10 +298,9 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||||
$documentation: "Base class for all statements introducing a lexical scope",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
directives: "[string*/S] an array of directives declared in this scope",
|
|
||||||
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
|
|||||||
@@ -285,6 +285,10 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan) {
|
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan) {
|
||||||
var reduce_vars = rescan && compressor.option("reduce_vars");
|
var reduce_vars = rescan && compressor.option("reduce_vars");
|
||||||
|
// Stack of look-up tables to keep track of whether a `SymbolDef` has been
|
||||||
|
// properly assigned before use:
|
||||||
|
// - `push()` & `pop()` when visiting conditional branches
|
||||||
|
// - backup & restore via `save_ids` when visiting out-of-order sections
|
||||||
var safe_ids = Object.create(null);
|
var safe_ids = Object.create(null);
|
||||||
var suppressor = new TreeWalker(function(node) {
|
var suppressor = new TreeWalker(function(node) {
|
||||||
if (!(node instanceof AST_Symbol)) return;
|
if (!(node instanceof AST_Symbol)) return;
|
||||||
@@ -391,10 +395,9 @@ merge(Compressor.prototype, {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Accessor) {
|
if (node instanceof AST_Accessor) {
|
||||||
var save_ids = safe_ids;
|
push();
|
||||||
safe_ids = Object.create(null);
|
|
||||||
descend();
|
descend();
|
||||||
safe_ids = save_ids;
|
pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Binary
|
if (node instanceof AST_Binary
|
||||||
@@ -561,6 +564,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function is_lhs_read_only(lhs) {
|
function is_lhs_read_only(lhs) {
|
||||||
|
if (lhs instanceof AST_This) return true;
|
||||||
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
||||||
if (lhs instanceof AST_PropAccess) {
|
if (lhs instanceof AST_PropAccess) {
|
||||||
lhs = lhs.expression;
|
lhs = lhs.expression;
|
||||||
@@ -745,7 +749,7 @@ merge(Compressor.prototype, {
|
|||||||
while (candidates.length > 0) {
|
while (candidates.length > 0) {
|
||||||
var candidate = candidates.pop();
|
var candidate = candidates.pop();
|
||||||
var lhs = get_lhs(candidate);
|
var lhs = get_lhs(candidate);
|
||||||
if (!lhs || is_lhs_read_only(lhs)) continue;
|
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
|
||||||
// Locate symbols which may execute code outside of scanning range
|
// Locate symbols which may execute code outside of scanning range
|
||||||
var lvalues = get_lvalues(candidate);
|
var lvalues = get_lvalues(candidate);
|
||||||
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
||||||
@@ -841,6 +845,8 @@ merge(Compressor.prototype, {
|
|||||||
&& !fn.uses_eval
|
&& !fn.uses_eval
|
||||||
&& (iife = compressor.parent()) instanceof AST_Call
|
&& (iife = compressor.parent()) instanceof AST_Call
|
||||||
&& iife.expression === fn) {
|
&& iife.expression === fn) {
|
||||||
|
var fn_strict = compressor.has_directive("use strict");
|
||||||
|
if (fn_strict && fn.body.indexOf(fn_strict) < 0) fn_strict = false;
|
||||||
var names = Object.create(null);
|
var names = Object.create(null);
|
||||||
for (var i = fn.argnames.length; --i >= 0;) {
|
for (var i = fn.argnames.length; --i >= 0;) {
|
||||||
var sym = fn.argnames[i];
|
var sym = fn.argnames[i];
|
||||||
@@ -858,7 +864,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
arg = null;
|
arg = null;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_This && !tw.find_parent(AST_Scope)) {
|
if (node instanceof AST_This && (fn_strict || !tw.find_parent(AST_Scope))) {
|
||||||
arg = null;
|
arg = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3496,7 +3502,7 @@ merge(Compressor.prototype, {
|
|||||||
&& (left.operator == "++" || left.operator == "--")) {
|
&& (left.operator == "++" || left.operator == "--")) {
|
||||||
left = left.expression;
|
left = left.expression;
|
||||||
} else left = null;
|
} else left = null;
|
||||||
if (!left || is_lhs_read_only(left)) {
|
if (!left || is_lhs_read_only(left) || left.has_side_effects(compressor)) {
|
||||||
expressions[++i] = cdr;
|
expressions[++i] = cdr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,13 +482,17 @@ function OutputStream(options) {
|
|||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
};
|
||||||
|
|
||||||
var use_asm = false;
|
|
||||||
var in_directive = false;
|
var in_directive = false;
|
||||||
|
var active_scope = null;
|
||||||
|
var use_asm = null;
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
var self = this, generator = self._codegen;
|
||||||
if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) {
|
if (self instanceof AST_Scope) {
|
||||||
use_asm = true;
|
active_scope = self;
|
||||||
|
}
|
||||||
|
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
|
||||||
|
use_asm = active_scope;
|
||||||
}
|
}
|
||||||
function doit() {
|
function doit() {
|
||||||
self.add_comments(stream);
|
self.add_comments(stream);
|
||||||
@@ -502,8 +506,8 @@ function OutputStream(options) {
|
|||||||
doit();
|
doit();
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
if (self instanceof AST_Scope) {
|
if (self === use_asm) {
|
||||||
use_asm = prev_use_asm;
|
use_asm = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
||||||
@@ -1109,7 +1113,7 @@ function OutputStream(options) {
|
|||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
||||||
return;
|
return;
|
||||||
if (self.expression instanceof AST_Lambda) {
|
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||||
output.add_mapping(self.start);
|
output.add_mapping(self.start);
|
||||||
}
|
}
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
|
|||||||
@@ -1054,6 +1054,8 @@ function parse($TEXT, options) {
|
|||||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||||
if (in_statement && !name)
|
if (in_statement && !name)
|
||||||
unexpected();
|
unexpected();
|
||||||
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
|
unexpected(prev());
|
||||||
expect("(");
|
expect("(");
|
||||||
var argnames = [];
|
var argnames = [];
|
||||||
for (var first = true; !is("punc", ")");) {
|
for (var first = true; !is("punc", ")");) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.1.0",
|
"version": "3.1.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -104,3 +104,65 @@ asm_mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm_toplevel: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
(function(){
|
||||||
|
0.0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_function_expression: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
var a = function() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
return function(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_nested_functions: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
function a() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function b() {
|
||||||
|
0.0;
|
||||||
|
function c(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function d(){
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
||||||
|
}
|
||||||
|
|||||||
@@ -2384,3 +2384,140 @@ issue_2298: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2313_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
if (this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
this.c && console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function a() {
|
||||||
|
a && c++;
|
||||||
|
var a = 0;
|
||||||
|
a && c++;
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
!function a() {
|
||||||
|
a && c++;
|
||||||
|
var a = 0;
|
||||||
|
a && c++;
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return !function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
"use strict";
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
"use strict";
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return !function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -385,3 +385,217 @@ set_mutable_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2313_1: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_5: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_6: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2549,7 +2549,7 @@ issue_1922_2: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
accessor: {
|
accessor_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -2578,6 +2578,33 @@ accessor: {
|
|||||||
expect_stdout: "1 1"
|
expect_stdout: "1 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessor_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var A = 1;
|
||||||
|
var B = {
|
||||||
|
get c() {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
B.c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
get c() {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
}).c;
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
for_in_prop: {
|
for_in_prop: {
|
||||||
options = {
|
options = {
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
|||||||
@@ -739,3 +739,44 @@ issue_2062: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2313: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
if (this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
return a++, 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
if (this.c++, this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|||||||
10
test/input/issue-2310/input.js
Normal file
10
test/input/issue-2310/input.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
function foo() {
|
||||||
|
return function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var f = foo();
|
||||||
|
f();
|
||||||
|
})();
|
||||||
@@ -573,6 +573,25 @@ describe("bin/uglifyjs", function () {
|
|||||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should include function calls in source map", function(done) {
|
||||||
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-2310/input.js",
|
||||||
|
"-c",
|
||||||
|
"--source-map", "url=inline",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||||
|
""
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should dump AST as JSON", function(done) {
|
it("Should dump AST as JSON", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not parse invalid use of reserved words", function() {
|
||||||
|
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
||||||
|
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
||||||
|
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
||||||
|
});
|
||||||
|
|
||||||
describe("keep_quoted_props", function() {
|
describe("keep_quoted_props", function() {
|
||||||
it("Should preserve quotes in object literals", function() {
|
it("Should preserve quotes in object literals", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
|
|||||||
Reference in New Issue
Block a user