Merge branch 'master' into harmony-v3.1.5
This commit is contained in:
116
lib/compress.js
116
lib/compress.js
@@ -157,7 +157,7 @@ merge(Compressor.prototype, {
|
||||
var last_count = 1 / 0;
|
||||
for (var pass = 0; pass < passes; pass++) {
|
||||
if (pass > 0 || this.option("reduce_vars"))
|
||||
node.reset_opt_flags(this, true);
|
||||
node.reset_opt_flags(this);
|
||||
node = node.transform(this);
|
||||
if (passes > 1) {
|
||||
var count = 0;
|
||||
@@ -289,8 +289,9 @@ merge(Compressor.prototype, {
|
||||
self.transform(tt);
|
||||
});
|
||||
|
||||
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan) {
|
||||
var reduce_vars = rescan && compressor.option("reduce_vars");
|
||||
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor) {
|
||||
var reduce_vars = compressor.option("reduce_vars");
|
||||
var unused = compressor.option("unused");
|
||||
// Stack of look-up tables to keep track of whether a `SymbolDef` has been
|
||||
// properly assigned before use:
|
||||
// - `push()` & `pop()` when visiting conditional branches
|
||||
@@ -315,16 +316,31 @@ merge(Compressor.prototype, {
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
var d = node.definition();
|
||||
d.references.push(node);
|
||||
if (d.fixed === undefined || !safe_to_read(d)
|
||||
|| is_modified(node, 0, is_immutable(node))) {
|
||||
if (d.fixed === undefined || !safe_to_read(d) || d.single_use == "m") {
|
||||
d.fixed = false;
|
||||
} else {
|
||||
var parent = tw.parent();
|
||||
if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
|
||||
|| parent instanceof AST_Call && node !== parent.expression
|
||||
|| parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
|
||||
|| parent instanceof AST_VarDef && node === parent.value) {
|
||||
d.escaped = true;
|
||||
var value = node.fixed_value();
|
||||
if (unused) {
|
||||
d.single_use = value
|
||||
&& d.references.length == 1
|
||||
&& loop_ids[d.id] === in_loop
|
||||
&& d.scope === node.scope
|
||||
&& value.is_constant_expression();
|
||||
}
|
||||
if (is_modified(node, 0, is_immutable(value))) {
|
||||
if (d.single_use) {
|
||||
d.single_use = "m";
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
} else {
|
||||
var parent = tw.parent();
|
||||
if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
|
||||
|| parent instanceof AST_Call && node !== parent.expression
|
||||
|| parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
|
||||
|| parent instanceof AST_VarDef && node === parent.value) {
|
||||
d.escaped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,8 +435,7 @@ merge(Compressor.prototype, {
|
||||
pop();
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Binary
|
||||
&& (node.operator == "&&" || node.operator == "||")) {
|
||||
if (node instanceof AST_Binary && lazy_op(node.operator)) {
|
||||
node.left.walk(tw);
|
||||
push();
|
||||
node.right.walk(tw);
|
||||
@@ -567,20 +582,8 @@ merge(Compressor.prototype, {
|
||||
def.single_use = undefined;
|
||||
}
|
||||
|
||||
function is_immutable(node) {
|
||||
var value = node.fixed_value();
|
||||
if (!value) return false;
|
||||
if (value.is_constant()) return true;
|
||||
if (compressor.option("unused")) {
|
||||
var d = node.definition();
|
||||
if (d.single_use === undefined) {
|
||||
d.single_use = loop_ids[d.id] === in_loop
|
||||
&& d.scope === node.scope
|
||||
&& value.is_constant_expression();
|
||||
}
|
||||
if (d.references.length == 1 && d.single_use) return true;
|
||||
}
|
||||
return value instanceof AST_Lambda;
|
||||
function is_immutable(value) {
|
||||
return value && (value.is_constant() || value instanceof AST_Lambda);
|
||||
}
|
||||
|
||||
function is_modified(node, level, immutable) {
|
||||
@@ -818,6 +821,7 @@ merge(Compressor.prototype, {
|
||||
// Locate symbols which may execute code outside of scanning range
|
||||
var lvalues = get_lvalues(candidate);
|
||||
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
||||
var one_off = lhs instanceof AST_Symbol && lhs.definition().references.length == 1;
|
||||
var side_effects = value_has_side_effects(candidate);
|
||||
var hit = candidate.name instanceof AST_SymbolFunarg;
|
||||
var abort = false, replaced = false;
|
||||
@@ -879,17 +883,18 @@ merge(Compressor.prototype, {
|
||||
var sym;
|
||||
if (node instanceof AST_Call
|
||||
|| node instanceof AST_Exit
|
||||
|| node instanceof AST_PropAccess && node.has_side_effects(compressor)
|
||||
|| node instanceof AST_PropAccess
|
||||
&& (side_effects || node.expression.may_throw_on_access(compressor))
|
||||
|| node instanceof AST_SymbolRef
|
||||
&& (lvalues[node.name]
|
||||
|| side_effects && !references_in_scope(node.definition()))
|
||||
|| (sym = lhs_or_def(node)) && get_symbol(sym).name in lvalues
|
||||
|| parent instanceof AST_Binary
|
||||
&& (parent.operator == "&&" || parent.operator == "||")
|
||||
|| parent instanceof AST_Case
|
||||
|| parent instanceof AST_Conditional
|
||||
|| parent instanceof AST_For
|
||||
|| parent instanceof AST_If) {
|
||||
|| (sym = lhs_or_def(node))
|
||||
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
||||
|| (side_effects || !one_off)
|
||||
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
||||
|| parent instanceof AST_Case
|
||||
|| parent instanceof AST_Conditional
|
||||
|| parent instanceof AST_If)) {
|
||||
if (!(node instanceof AST_Scope)) descend(node, tt);
|
||||
abort = true;
|
||||
return node;
|
||||
@@ -1002,27 +1007,14 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
|
||||
function get_symbol(node) {
|
||||
while (node instanceof AST_PropAccess) node = node.expression;
|
||||
return node;
|
||||
}
|
||||
|
||||
function get_lvalues(expr) {
|
||||
var lvalues = Object.create(null);
|
||||
if (expr instanceof AST_Unary) return lvalues;
|
||||
var scope;
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_Scope) {
|
||||
var save_scope = scope;
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef || node instanceof AST_PropAccess) {
|
||||
var sym = get_symbol(node);
|
||||
if (sym instanceof AST_SymbolRef) {
|
||||
lvalues[sym.name] = lvalues[sym.name] || is_lhs(node, tw.parent());
|
||||
}
|
||||
var sym = node;
|
||||
while (sym instanceof AST_PropAccess) sym = sym.expression;
|
||||
if (sym instanceof AST_SymbolRef || sym instanceof AST_This) {
|
||||
lvalues[sym.name] = lvalues[sym.name] || is_lhs(node, tw.parent());
|
||||
}
|
||||
});
|
||||
expr[expr instanceof AST_Assign ? "right" : "value"].walk(tw);
|
||||
@@ -1521,9 +1513,10 @@ merge(Compressor.prototype, {
|
||||
return member(this.operator, unary_bool);
|
||||
});
|
||||
def(AST_Binary, function(){
|
||||
return member(this.operator, binary_bool) ||
|
||||
( (this.operator == "&&" || this.operator == "||") &&
|
||||
this.left.is_boolean() && this.right.is_boolean() );
|
||||
return member(this.operator, binary_bool)
|
||||
|| lazy_op(this.operator)
|
||||
&& this.left.is_boolean()
|
||||
&& this.right.is_boolean();
|
||||
});
|
||||
def(AST_Conditional, function(){
|
||||
return this.consequent.is_boolean() && this.alternative.is_boolean();
|
||||
@@ -1595,6 +1588,7 @@ merge(Compressor.prototype, {
|
||||
node.DEFMETHOD("is_string", func);
|
||||
});
|
||||
|
||||
var lazy_op = makePredicate("&& ||");
|
||||
var unary_side_effects = makePredicate("delete ++ --");
|
||||
|
||||
function is_lhs(node, parent) {
|
||||
@@ -2861,14 +2855,12 @@ merge(Compressor.prototype, {
|
||||
def(AST_Binary, function(compressor, first_in_statement){
|
||||
var right = this.right.drop_side_effect_free(compressor);
|
||||
if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
|
||||
switch (this.operator) {
|
||||
case "&&":
|
||||
case "||":
|
||||
if (lazy_op(this.operator)) {
|
||||
if (right === this.right) return this;
|
||||
var node = this.clone();
|
||||
node.right = right;
|
||||
return node;
|
||||
default:
|
||||
} else {
|
||||
var left = this.left.drop_side_effect_free(compressor, first_in_statement);
|
||||
if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
|
||||
return make_sequence(this, [ left, right ]);
|
||||
@@ -3792,7 +3784,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) {
|
||||
if (cdr.left.is_constant()) {
|
||||
if (cdr.operator == "||" || cdr.operator == "&&") {
|
||||
if (lazy_op(cdr.operator)) {
|
||||
expressions[++i] = expressions[j];
|
||||
break;
|
||||
}
|
||||
@@ -4292,8 +4284,7 @@ merge(Compressor.prototype, {
|
||||
// "x" + (y + "z")==> "x" + y + "z"
|
||||
if (self.right instanceof AST_Binary
|
||||
&& self.right.operator == self.operator
|
||||
&& (self.operator == "&&"
|
||||
|| self.operator == "||"
|
||||
&& (lazy_op(self.operator)
|
||||
|| (self.operator == "+"
|
||||
&& (self.right.left.is_string(compressor)
|
||||
|| (self.left.is_string(compressor)
|
||||
@@ -4345,6 +4336,7 @@ merge(Compressor.prototype, {
|
||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
||||
}
|
||||
if (compressor.option("unused")
|
||||
&& fixed
|
||||
&& d.references.length == 1
|
||||
&& (d.single_use || is_func_expr(fixed)
|
||||
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.1.4",
|
||||
"version": "3.1.5",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -2874,3 +2874,419 @@ prop_side_effects_2: {
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2365: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a.f;
|
||||
a.f++;
|
||||
return b;
|
||||
}({ f: 1 }));
|
||||
console.log(function() {
|
||||
var a = { f: 1 }, b = a.f;
|
||||
a.f++;
|
||||
return b;
|
||||
}());
|
||||
console.log({
|
||||
f: 1,
|
||||
g: function() {
|
||||
var b = this.f;
|
||||
this.f++;
|
||||
return b;
|
||||
}
|
||||
}.g());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a.f;
|
||||
a.f++;
|
||||
return b;
|
||||
}({ f: 1 }));
|
||||
console.log(function() {
|
||||
var a = { f: 1 }, b = a.f;
|
||||
a.f++;
|
||||
return b;
|
||||
}());
|
||||
console.log({
|
||||
f: 1,
|
||||
g: function() {
|
||||
var b = this.f;
|
||||
this.f++;
|
||||
return b;
|
||||
}
|
||||
}.g());
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2364_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo() {
|
||||
var first = arguments[0];
|
||||
var result = inc(first);
|
||||
return foo.amount = first.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0,
|
||||
};
|
||||
var answer = foo(data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo() {
|
||||
var first = arguments[0];
|
||||
var result = inc(first);
|
||||
return foo.amount = first.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0
|
||||
};
|
||||
var answer = foo(data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect_stdout: "1 0"
|
||||
}
|
||||
|
||||
issue_2364_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function callValidate() {
|
||||
var validate = compilation.validate;
|
||||
var result = validate.apply(null, arguments);
|
||||
return callValidate.errors = validate.errors, result;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function callValidate() {
|
||||
var validate = compilation.validate;
|
||||
var result = validate.apply(null, arguments);
|
||||
return callValidate.errors = validate.errors, result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2364_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo(bar) {
|
||||
var result = inc(bar);
|
||||
return foo.amount = bar.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0,
|
||||
};
|
||||
var answer = foo(data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo(bar) {
|
||||
var result = inc(bar);
|
||||
return foo.amount = bar.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0,
|
||||
};
|
||||
var answer = foo(data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect_stdout: "1 0"
|
||||
}
|
||||
|
||||
issue_2364_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo(bar, baz) {
|
||||
var result = inc(bar);
|
||||
return foo.amount = baz.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0,
|
||||
};
|
||||
var answer = foo(data, data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect: {
|
||||
function inc(obj) {
|
||||
return obj.count++;
|
||||
}
|
||||
function foo(bar, baz) {
|
||||
var result = inc(bar);
|
||||
return foo.amount = baz.count, result;
|
||||
}
|
||||
var data = {
|
||||
count: 0,
|
||||
};
|
||||
var answer = foo(data, data);
|
||||
console.log(foo.amount, answer);
|
||||
}
|
||||
expect_stdout: "1 0"
|
||||
}
|
||||
|
||||
issue_2364_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f0(o, a, h) {
|
||||
var b = 3 - a;
|
||||
var obj = o;
|
||||
var seven = 7;
|
||||
var prop = 'run';
|
||||
var t = obj[prop](b)[seven] = h;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f0(o, a, h) {
|
||||
return o.run(3 - a)[7] = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2364_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var c = a.p;
|
||||
b.p = "FAIL";
|
||||
return c;
|
||||
}
|
||||
var o = {
|
||||
p: "PASS"
|
||||
}
|
||||
console.log(f(o, o));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
var c = a.p;
|
||||
b.p = "FAIL";
|
||||
return c;
|
||||
}
|
||||
var o = {
|
||||
p: "PASS"
|
||||
}
|
||||
console.log(f(o, o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2364_7: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var c = a.p;
|
||||
b.f();
|
||||
return c;
|
||||
}
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: function() {
|
||||
this.p = "FAIL";
|
||||
}
|
||||
}
|
||||
console.log(f(o, o));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
var c = a.p;
|
||||
b.f();
|
||||
return c;
|
||||
}
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: function() {
|
||||
this.p = "FAIL";
|
||||
}
|
||||
}
|
||||
console.log(f(o, o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2364_8: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c) {
|
||||
var d = a[b.f = function() {
|
||||
return "PASS";
|
||||
}];
|
||||
return c.f(d);
|
||||
}
|
||||
var o = {
|
||||
f: function() {
|
||||
return "FAIL";
|
||||
}
|
||||
};
|
||||
console.log(f({}, o, o));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b, c) {
|
||||
var d = a[b.f = function() {
|
||||
return "PASS";
|
||||
}];
|
||||
return c.f(d);
|
||||
}
|
||||
var o = {
|
||||
f: function() {
|
||||
return "FAIL";
|
||||
}
|
||||
};
|
||||
console.log(f({}, o, o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2364_9: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var d = a();
|
||||
return b.f(d);
|
||||
}
|
||||
var o = {
|
||||
f: function() {
|
||||
return "FAIL";
|
||||
}
|
||||
};
|
||||
console.log(f(function() {
|
||||
o.f = function() {
|
||||
return "PASS";
|
||||
};
|
||||
}, o));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
var d = a();
|
||||
return b.f(d);
|
||||
}
|
||||
var o = {
|
||||
f: function() {
|
||||
return "FAIL";
|
||||
}
|
||||
};
|
||||
console.log(f(function() {
|
||||
o.f = function() {
|
||||
return "PASS";
|
||||
};
|
||||
}, o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
pure_getters_chain: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function o(t, r) {
|
||||
var a = t[1], s = t[2], o = t[3], i = t[5];
|
||||
return a <= 23 && s <= 59 && o <= 59 && (!r || i);
|
||||
}
|
||||
console.log(o([ , 23, 59, 59, , 42], 1));
|
||||
}
|
||||
expect: {
|
||||
function o(t, r) {
|
||||
return t[1] <= 23 && t[2] <= 59 && t[3] <= 59 && (!r || t[5]);
|
||||
}
|
||||
console.log(o([ , 23, 59, 59, , 42], 1));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
conditional_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var c = "";
|
||||
var d = b ? ">" : "<";
|
||||
if (a) c += "=";
|
||||
return c += d;
|
||||
}
|
||||
console.log(f(0, 0), f(0, 1), f(1, 0), f(1, 1));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
var c = "";
|
||||
if (a) c += "=";
|
||||
return c += b ? ">" : "<";
|
||||
}
|
||||
console.log(f(0, 0), f(0, 1), f(1, 0), f(1, 1));
|
||||
}
|
||||
expect_stdout: "< > =< =>"
|
||||
}
|
||||
|
||||
conditional_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var c = a + 1, d = a + 2;
|
||||
return b ? c : d;
|
||||
}
|
||||
console.log(f(3, 0), f(4, 1));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
return b ? a + 1 : a + 2;
|
||||
}
|
||||
console.log(f(3, 0), f(4, 1));
|
||||
}
|
||||
expect_stdout: "5 5"
|
||||
}
|
||||
|
||||
@@ -1190,10 +1190,10 @@ defun_label: {
|
||||
!function() {
|
||||
console.log(function(a) {
|
||||
L: {
|
||||
if (a) break L;
|
||||
if (2) break L;
|
||||
return 1;
|
||||
}
|
||||
}(2));
|
||||
}());
|
||||
}();
|
||||
}
|
||||
expect_stdout: true
|
||||
@@ -3051,3 +3051,63 @@ array_forof_2: {
|
||||
expect_stdout: "3"
|
||||
node_version: ">=0.12"
|
||||
}
|
||||
|
||||
const_expr_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.a++;
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.a++;
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
const_expr_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
Object.prototype.c = function() {
|
||||
this.a++;
|
||||
};
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.c();
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect: {
|
||||
Object.prototype.c = function() {
|
||||
this.a++;
|
||||
};
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.c();
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user