[Pkg-javascript-commits] [uglifyjs] 21/50: fix bugs with getter/setter (#1926)
Jonas Smedegaard
dr at jones.dk
Thu Aug 17 23:06:44 UTC 2017
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository uglifyjs.
commit a8c67ea353012963c7c550a1c03bf2db83b03d24
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Sun May 14 02:10:34 2017 +0800
fix bugs with getter/setter (#1926)
- `reduce_vars`
- `side_effects`
- property access for object
- `AST_SymbolAccessor` as key names
enhance `test/ufuzz.js`
- add object getter & setter
- property assignment to setter
- avoid infinite recursion in setter
- fix & adjust assignment operators
- 50% `=`
- 25% `+=`
- 2.5% each for the rest
- avoid "Invalid array length"
- fix `console.log()`
- bypass getter
- curb recursive reference
- deprecate `-E`, always report runtime errors
---
lib/ast.js | 4 +-
lib/compress.js | 110 ++++++++++++++++++++++------------
lib/parse.js | 9 ++-
lib/scope.js | 5 --
test/compress/dead-code.js | 16 +++++
test/compress/pure_getters.js | 59 +++++++++++++++++++
test/compress/reduce_vars.js | 29 +++++++++
test/mocha/accessorTokens-1492.js | 2 +-
test/mocha/getter-setter.js | 2 +-
test/sandbox.js | 12 ++--
test/ufuzz.js | 121 +++++++++++++++++++++++++++-----------
11 files changed, 284 insertions(+), 85 deletions(-)
diff --git a/lib/ast.js b/lib/ast.js
index cdf75d4..028772f 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -798,8 +798,8 @@ var AST_Object = DEFNODE("Object", "properties", {
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
$documentation: "Base class for literal object properties",
$propdoc: {
- key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
- value: "[AST_Node] property value. For setters and getters this is an AST_Function."
+ key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
+ value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
},
_walk: function(visitor) {
return visitor._visit(this, function(){
diff --git a/lib/compress.js b/lib/compress.js
index d0f9668..c3adcc5 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -316,25 +316,55 @@ merge(Compressor.prototype, {
safe_ids = save_ids;
return true;
}
- var iife;
- if (node instanceof AST_Function
- && !node.name
- && (iife = tw.parent()) instanceof AST_Call
- && iife.expression === node) {
- // Virtually turn IIFE parameters into variable definitions:
- // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
- // So existing transformation rules can work on them.
- node.argnames.forEach(function(arg, i) {
- var d = arg.definition();
- if (!node.uses_arguments && d.fixed === undefined) {
- d.fixed = function() {
- return iife.args[i] || make_node(AST_Undefined, iife);
- };
- mark(d, true);
- } else {
- d.fixed = false;
- }
- });
+ if (node instanceof AST_Function) {
+ push();
+ var iife;
+ if (!node.name
+ && (iife = tw.parent()) instanceof AST_Call
+ && iife.expression === node) {
+ // Virtually turn IIFE parameters into variable definitions:
+ // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
+ // So existing transformation rules can work on them.
+ node.argnames.forEach(function(arg, i) {
+ var d = arg.definition();
+ if (!node.uses_arguments && d.fixed === undefined) {
+ d.fixed = function() {
+ return iife.args[i] || make_node(AST_Undefined, iife);
+ };
+ mark(d, true);
+ } else {
+ d.fixed = false;
+ }
+ });
+ }
+ descend();
+ pop();
+ return true;
+ }
+ if (node instanceof AST_Accessor) {
+ var save_ids = safe_ids;
+ safe_ids = Object.create(null);
+ descend();
+ safe_ids = save_ids;
+ return true;
+ }
+ if (node instanceof AST_Binary
+ && (node.operator == "&&" || node.operator == "||")) {
+ node.left.walk(tw);
+ push();
+ node.right.walk(tw);
+ pop();
+ return true;
+ }
+ if (node instanceof AST_Conditional) {
+ node.condition.walk(tw);
+ push();
+ node.consequent.walk(tw);
+ pop();
+ push();
+ node.alternative.walk(tw);
+ pop();
+ return true;
}
if (node instanceof AST_If || node instanceof AST_DWLoop) {
node.condition.walk(tw);
@@ -1195,12 +1225,12 @@ merge(Compressor.prototype, {
&& !node.expression.has_side_effects(compressor);
}
- // may_eq_null()
- // returns true if this node may evaluate to null or undefined
+ // may_throw_on_access()
+ // returns true if this node may be null, undefined or contain `AST_Accessor`
(function(def) {
- AST_Node.DEFMETHOD("may_eq_null", function(compressor) {
+ AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
var pure_getters = compressor.option("pure_getters");
- return !pure_getters || this._eq_null(pure_getters);
+ return !pure_getters || this._throw_on_access(pure_getters);
});
function is_strict(pure_getters) {
@@ -1212,7 +1242,12 @@ merge(Compressor.prototype, {
def(AST_Undefined, return_true);
def(AST_Constant, return_false);
def(AST_Array, return_false);
- def(AST_Object, return_false);
+ def(AST_Object, function(pure_getters) {
+ if (!is_strict(pure_getters)) return false;
+ for (var i = this.properties.length; --i >=0;)
+ if (this.properties[i].value instanceof AST_Accessor) return true;
+ return false;
+ });
def(AST_Function, return_false);
def(AST_UnaryPostfix, return_false);
def(AST_UnaryPrefix, function() {
@@ -1221,33 +1256,33 @@ merge(Compressor.prototype, {
def(AST_Binary, function(pure_getters) {
switch (this.operator) {
case "&&":
- return this.left._eq_null(pure_getters);
+ return this.left._throw_on_access(pure_getters);
case "||":
- return this.left._eq_null(pure_getters)
- && this.right._eq_null(pure_getters);
+ return this.left._throw_on_access(pure_getters)
+ && this.right._throw_on_access(pure_getters);
default:
return false;
}
})
def(AST_Assign, function(pure_getters) {
return this.operator == "="
- && this.right._eq_null(pure_getters);
+ && this.right._throw_on_access(pure_getters);
})
def(AST_Conditional, function(pure_getters) {
- return this.consequent._eq_null(pure_getters)
- || this.alternative._eq_null(pure_getters);
+ return this.consequent._throw_on_access(pure_getters)
+ || this.alternative._throw_on_access(pure_getters);
})
def(AST_Seq, function(pure_getters) {
- return this.cdr._eq_null(pure_getters);
+ return this.cdr._throw_on_access(pure_getters);
});
def(AST_SymbolRef, function(pure_getters) {
if (this.is_undefined) return true;
if (!is_strict(pure_getters)) return false;
var fixed = this.fixed_value();
- return !fixed || fixed._eq_null(pure_getters);
+ return !fixed || fixed._throw_on_access(pure_getters);
});
})(function(node, func) {
- node.DEFMETHOD("_eq_null", func);
+ node.DEFMETHOD("_throw_on_access", func);
});
/* -----[ boolean/negation helpers ]----- */
@@ -1787,11 +1822,11 @@ merge(Compressor.prototype, {
return any(this.elements, compressor);
});
def(AST_Dot, function(compressor){
- return this.expression.may_eq_null(compressor)
+ return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
});
def(AST_Sub, function(compressor){
- return this.expression.may_eq_null(compressor)
+ return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor);
});
@@ -2295,6 +2330,7 @@ merge(Compressor.prototype, {
var args = trim(this.args, compressor, first_in_statement);
return args && AST_Seq.from_array(args);
});
+ def(AST_Accessor, return_null);
def(AST_Function, return_null);
def(AST_Binary, function(compressor, first_in_statement){
var right = this.right.drop_side_effect_free(compressor);
@@ -2365,11 +2401,11 @@ merge(Compressor.prototype, {
return values && AST_Seq.from_array(values);
});
def(AST_Dot, function(compressor, first_in_statement){
- if (this.expression.may_eq_null(compressor)) return this;
+ if (this.expression.may_throw_on_access(compressor)) return this;
return this.expression.drop_side_effect_free(compressor, first_in_statement);
});
def(AST_Sub, function(compressor, first_in_statement){
- if (this.expression.may_eq_null(compressor)) return this;
+ if (this.expression.may_throw_on_access(compressor)) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
var property = this.property.drop_side_effect_free(compressor);
diff --git a/lib/parse.js b/lib/parse.js
index 6055a39..bf18d9d 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -1320,10 +1320,15 @@ function parse($TEXT, options) {
var type = start.type;
var name = as_property_name();
if (type == "name" && !is("punc", ":")) {
+ var key = new AST_SymbolAccessor({
+ start: S.token,
+ name: as_property_name(),
+ end: prev()
+ });
if (name == "get") {
a.push(new AST_ObjectGetter({
start : start,
- key : as_atom_node(),
+ key : key,
value : create_accessor(),
end : prev()
}));
@@ -1332,7 +1337,7 @@ function parse($TEXT, options) {
if (name == "set") {
a.push(new AST_ObjectSetter({
start : start,
- key : as_atom_node(),
+ key : key,
value : create_accessor(),
end : prev()
}));
diff --git a/lib/scope.js b/lib/scope.js
index 74760e4..bf6dbcb 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -361,11 +361,6 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
return this.definition().unmangleable(options);
});
-// property accessors are not mangleable
-AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
- return true;
-});
-
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", function(){
return false;
diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js
index bb72451..af28e25 100644
--- a/test/compress/dead-code.js
+++ b/test/compress/dead-code.js
@@ -256,3 +256,19 @@ try_catch_finally: {
"1",
]
}
+
+accessor: {
+ options = {
+ side_effects: true,
+ }
+ input: {
+ ({
+ get a() {},
+ set a(v){
+ this.b = 2;
+ },
+ b: 1
+ });
+ }
+ expect: {}
+}
diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js
index 846b53c..0ca6a80 100644
--- a/test/compress/pure_getters.js
+++ b/test/compress/pure_getters.js
@@ -119,3 +119,62 @@ chained: {
a.b.c;
}
}
+
+impure_getter_1: {
+ options = {
+ pure_getters: "strict",
+ side_effects: true,
+ }
+ input: {
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).a;
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).b;
+ }
+ expect: {
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).a;
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).b;
+ }
+ expect_stdout: "1"
+}
+
+impure_getter_2: {
+ options = {
+ pure_getters: true,
+ side_effects: true,
+ }
+ input: {
+ // will produce incorrect output because getter is not pure
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).a;
+ ({
+ get a() {
+ console.log(1);
+ },
+ b: 1
+ }).b;
+ }
+ expect: {}
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 767311d..1cd8bfa 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -2169,3 +2169,32 @@ issue_1922_2: {
}
expect_stdout: "1"
}
+
+accessor: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ toplevel: true,
+ }
+ input: {
+ var a = 1;
+ console.log({
+ get a() {
+ a = 2;
+ return a;
+ },
+ b: 1
+ }.b, a);
+ }
+ expect: {
+ var a = 1;
+ console.log({
+ get a() {
+ a = 2;
+ return a;
+ },
+ b: 1
+ }.b, a);
+ }
+ expect_stdout: "1 1"
+}
diff --git a/test/mocha/accessorTokens-1492.js b/test/mocha/accessorTokens-1492.js
index 861414e..d4db222 100644
--- a/test/mocha/accessorTokens-1492.js
+++ b/test/mocha/accessorTokens-1492.js
@@ -16,7 +16,7 @@ describe("Accessor tokens", function() {
assert.equal(node.start.pos, 12);
assert.equal(node.end.endpos, 46);
- assert(node.key instanceof UglifyJS.AST_SymbolRef);
+ assert(node.key instanceof UglifyJS.AST_SymbolAccessor);
assert.equal(node.key.start.pos, 16);
assert.equal(node.key.end.endpos, 22);
diff --git a/test/mocha/getter-setter.js b/test/mocha/getter-setter.js
index 641a202..ddd17f1 100644
--- a/test/mocha/getter-setter.js
+++ b/test/mocha/getter-setter.js
@@ -71,7 +71,7 @@ describe("Getters and setters", function() {
var fail = function(data) {
return function (e) {
return e instanceof UglifyJS.JS_Parse_Error &&
- e.message === "Invalid getter/setter name: " + data.operator;
+ e.message === "Unexpected token: operator (" + data.operator + ")";
};
};
diff --git a/test/sandbox.js b/test/sandbox.js
index eb9f1f0..c155f91 100644
--- a/test/sandbox.js
+++ b/test/sandbox.js
@@ -1,14 +1,16 @@
var vm = require("vm");
-function safe_log(arg) {
+function safe_log(arg, level) {
if (arg) switch (typeof arg) {
case "function":
return arg.toString();
case "object":
if (/Error$/.test(arg.name)) return arg.toString();
arg.constructor.toString();
- for (var key in arg) {
- arg[key] = safe_log(arg[key]);
+ if (level--) for (var key in arg) {
+ if (!Object.getOwnPropertyDescriptor(arg, key).get) {
+ arg[key] = safe_log(arg[key], level);
+ }
}
}
return arg;
@@ -48,7 +50,9 @@ exports.run_code = function(code) {
].join("\n"), {
console: {
log: function() {
- return console.log.apply(console, [].map.call(arguments, safe_log));
+ return console.log.apply(console, [].map.call(arguments, function(arg) {
+ return safe_log(arg, 3);
+ }));
}
}
}, { timeout: 5000 });
diff --git a/test/ufuzz.js b/test/ufuzz.js
index 22f17c3..4c0eddb 100644
--- a/test/ufuzz.js
+++ b/test/ufuzz.js
@@ -48,7 +48,6 @@ var STMT_COUNT_FROM_GLOBAL = true; // count statement depth from nearest functio
var num_iterations = +process.argv[2] || 1/0;
var verbose = false; // log every generated test
var verbose_interval = false; // log every 100 generated tests
-var verbose_error = false;
var use_strict = false;
for (var i = 2; i < process.argv.length; ++i) {
switch (process.argv[i]) {
@@ -58,9 +57,6 @@ for (var i = 2; i < process.argv.length; ++i) {
case '-V':
verbose_interval = true;
break;
- case '-E':
- verbose_error = true;
- break;
case '-t':
MAX_GENERATED_TOPLEVELS_PER_RUN = +process.argv[++i];
if (!MAX_GENERATED_TOPLEVELS_PER_RUN) throw new Error('Must generate at least one toplevel per run');
@@ -103,7 +99,6 @@ for (var i = 2; i < process.argv.length; ++i) {
console.log('<number>: generate this many cases (if used must be first arg)');
console.log('-v: print every generated test case');
console.log('-V: print every 100th generated test case');
- console.log('-E: print generated test case with runtime error');
console.log('-t <int>: generate this many toplevels per run (more take longer)');
console.log('-r <int>: maximum recursion depth for generator (higher takes longer)');
console.log('-s1 <statement name>: force the first level statement to be this one (see list below)');
@@ -192,12 +187,33 @@ var ASSIGNMENTS = [
'=',
'=',
'=',
+ '=',
+ '=',
+ '=',
+ '=',
- '==',
- '!=',
- '===',
- '!==',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+ '=',
+
+ '+=',
+ '+=',
+ '+=',
+ '+=',
'+=',
+ '+=',
+ '+=',
+ '+=',
+ '+=',
+ '+=',
+
'-=',
'*=',
'/=',
@@ -207,7 +223,8 @@ var ASSIGNMENTS = [
'<<=',
'>>=',
'>>>=',
- '%=' ];
+ '%=',
+];
var UNARY_SAFE = [
'+',
@@ -359,7 +376,6 @@ function createFunction(recurmax, inGlobal, noDecl, canThrow, stmtDepth) {
// avoid "function statements" (decl inside statements)
else if (inGlobal || rng(10) > 0) s += 'var ' + createVarName(MANDATORY) + ' = ' + name + '(' + createArgs() + ');';
-
return s;
}
@@ -406,7 +422,7 @@ function getLabel(label) {
return label && " L" + label;
}
-function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
+function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth, target) {
++stmtDepth;
var loop = ++loops;
if (--recurmax < 0) {
@@ -414,10 +430,11 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
}
// allow to forcefully generate certain structures at first or second recursion level
- var target = 0;
- if (stmtDepth === 1 && STMT_FIRST_LEVEL_OVERRIDE >= 0) target = STMT_FIRST_LEVEL_OVERRIDE;
- else if (stmtDepth === 2 && STMT_SECOND_LEVEL_OVERRIDE >= 0) target = STMT_SECOND_LEVEL_OVERRIDE;
- else target = STMTS_TO_USE[rng(STMTS_TO_USE.length)];
+ if (target === undefined) {
+ if (stmtDepth === 1 && STMT_FIRST_LEVEL_OVERRIDE >= 0) target = STMT_FIRST_LEVEL_OVERRIDE;
+ else if (stmtDepth === 2 && STMT_SECOND_LEVEL_OVERRIDE >= 0) target = STMT_SECOND_LEVEL_OVERRIDE;
+ else target = STMTS_TO_USE[rng(STMTS_TO_USE.length)];
+ }
switch (target) {
case STMT_BLOCK:
@@ -636,7 +653,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
strictMode()
);
if (instantiate) for (var i = rng(4); --i >= 0;) {
- if (rng(2)) s.push('this.' + getDotKey() + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ';');
+ if (rng(2)) s.push('this.' + getDotKey(true) + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ';');
else s.push('this[' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ']' + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ';');
}
s.push(
@@ -689,19 +706,19 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
") || " + rng(10) + ").toString()[" +
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "] ";
case p++:
- return createArrayLiteral(recurmax, COMMA_OK, stmtDepth, canThrow);
+ return createArrayLiteral(recurmax, stmtDepth, canThrow);
case p++:
- return createObjectLiteral(recurmax, COMMA_OK, stmtDepth, canThrow);
+ return createObjectLiteral(recurmax, stmtDepth, canThrow);
case p++:
- return createArrayLiteral(recurmax, COMMA_OK, stmtDepth, canThrow) + '[' +
+ return createArrayLiteral(recurmax, stmtDepth, canThrow) + '[' +
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ']';
case p++:
- return createObjectLiteral(recurmax, COMMA_OK, stmtDepth, canThrow) + '[' +
+ return createObjectLiteral(recurmax, stmtDepth, canThrow) + '[' +
createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ']';
case p++:
- return createArrayLiteral(recurmax, COMMA_OK, stmtDepth, canThrow) + '.' + getDotKey();
+ return createArrayLiteral(recurmax, stmtDepth, canThrow) + '.' + getDotKey();
case p++:
- return createObjectLiteral(recurmax, COMMA_OK, stmtDepth, canThrow) + '.' + getDotKey();
+ return createObjectLiteral(recurmax, stmtDepth, canThrow) + '.' + getDotKey();
case p++:
var name = getVarName();
return name + ' && ' + name + '[' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ']';
@@ -713,7 +730,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
return _createExpression(recurmax, noComma, stmtDepth, canThrow);
}
-function createArrayLiteral(recurmax, noComma, stmtDepth, canThrow) {
+function createArrayLiteral(recurmax, stmtDepth, canThrow) {
recurmax--;
var arr = "[";
for (var i = rng(6); --i >= 0;) {
@@ -746,18 +763,56 @@ var KEYS = [
"3",
].concat(SAFE_KEYS);
-function getDotKey() {
- return SAFE_KEYS[rng(SAFE_KEYS.length)];
+function getDotKey(assign) {
+ var key;
+ do {
+ key = SAFE_KEYS[rng(SAFE_KEYS.length)];
+ } while (assign && key == "length");
+ return key;
+}
+
+function createAccessor(recurmax, stmtDepth, canThrow) {
+ var namesLenBefore = VAR_NAMES.length;
+ var s;
+ var prop1 = getDotKey();
+ if (rng(2) == 0) {
+ s = [
+ 'get ' + prop1 + '(){',
+ strictMode(),
+ createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
+ createStatement(recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth, STMT_RETURN_ETC),
+ '},'
+ ].join('\n');
+ } else {
+ var prop2;
+ do {
+ prop2 = getDotKey();
+ } while (prop1 == prop2);
+ s = [
+ 'set ' + prop1 + '(' + createVarName(MANDATORY) + '){',
+ strictMode(),
+ createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
+ 'this.' + prop2 + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ';',
+ '},'
+ ].join('\n');
+ }
+ VAR_NAMES.length = namesLenBefore;
+ return s;
}
-function createObjectLiteral(recurmax, noComma, stmtDepth, canThrow) {
+function createObjectLiteral(recurmax, stmtDepth, canThrow) {
recurmax--;
- var obj = "({";
+ var obj = ['({'];
for (var i = rng(6); --i >= 0;) {
- var key = KEYS[rng(KEYS.length)];
- obj += key + ":(" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "), ";
+ if (rng(20) == 0) {
+ obj.push(createAccessor(recurmax, stmtDepth, canThrow));
+ } else {
+ var key = KEYS[rng(KEYS.length)];
+ obj.push(key + ':(' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + '),');
+ }
}
- return obj + "})";
+ obj.push('})');
+ return obj.join('\n');
}
function createNestedBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
@@ -787,7 +842,7 @@ function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
return canThrow && rng(10) == 0 ? expr : '(' + assignee + ' && ' + expr + ')';
case 4:
assignee = getVarName();
- expr = '(' + assignee + '.' + getDotKey() + createAssignment()
+ expr = '(' + assignee + '.' + getDotKey(true) + createAssignment()
+ _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ')';
return canThrow && rng(10) == 0 ? expr : '(' + assignee + ' && ' + expr + ')';
default:
@@ -999,7 +1054,7 @@ for (var round = 1; round <= num_iterations; round++) {
ok = uglify_code.name == original_result.name;
}
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
- else if (verbose_error && typeof original_result != "string") {
+ else if (typeof original_result != "string") {
console.log("//=============================================================");
console.log("// original code");
try_beautify(original_code, original_result);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list