aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-04-30 04:40:47 +0100
committerGitHub <noreply@github.com>2021-04-30 11:40:47 +0800
commitd833e66d23cab3c9c03a99a9cf118647bf862868 (patch)
tree7735f135c2fa716cdd978e835e4922ba7a794d8f
parent8aa650bcf95853a930e047350cc9040b42a3c567 (diff)
downloadtracifyjs-d833e66d23cab3c9c03a99a9cf118647bf862868.tar.gz
tracifyjs-d833e66d23cab3c9c03a99a9cf118647bf862868.zip
enhance `join_vars` (#4881)
-rw-r--r--lib/compress.js30
-rw-r--r--test/compress/join_vars.js60
-rw-r--r--test/ufuzz/index.js16
3 files changed, 87 insertions, 19 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 3847015d..384e0e89 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3396,12 +3396,14 @@ merge(Compressor.prototype, {
if (prop instanceof AST_Node) break;
prop = "" + prop;
var diff = prop == "__proto__" || compressor.has_directive("use strict") ? function(node) {
- return typeof node.key == "string" && node.key != prop;
+ var key = node.key;
+ return typeof key == "string" && key != prop && key != "__proto__";
} : function(node) {
+ var key = node.key;
if (node instanceof AST_ObjectGetter || node instanceof AST_ObjectSetter) {
- return typeof node.key == "string" && node.key != prop;
+ return typeof key == "string" && key != prop;
}
- return true;
+ return key !== "__proto__";
};
if (!all(value.properties, diff)) break;
value.properties.push(make_node(AST_ObjectKeyVal, node, {
@@ -5141,12 +5143,12 @@ merge(Compressor.prototype, {
return true;
}
def(AST_Node, return_false);
- def(AST_Array, function() {
- return all_constant(this.elements);
+ def(AST_Array, function(scope) {
+ return all_constant(this.elements, scope);
});
- def(AST_Binary, function() {
- return this.left.is_constant_expression()
- && this.right.is_constant_expression()
+ def(AST_Binary, function(scope) {
+ return this.left.is_constant_expression(scope)
+ && this.right.is_constant_expression(scope)
&& (this.operator != "in" || is_object(this.right));
});
def(AST_Class, function(scope) {
@@ -5198,14 +5200,14 @@ merge(Compressor.prototype, {
}));
return result;
});
- def(AST_Object, function() {
- return all_constant(this.properties);
+ def(AST_Object, function(scope) {
+ return all_constant(this.properties, scope);
});
- def(AST_ObjectProperty, function() {
- return typeof this.key == "string" && this.value.is_constant_expression();
+ def(AST_ObjectProperty, function(scope) {
+ return typeof this.key == "string" && this.value.is_constant_expression(scope);
});
- def(AST_Unary, function() {
- return this.expression.is_constant_expression();
+ def(AST_Unary, function(scope) {
+ return this.expression.is_constant_expression(scope);
});
})(function(node, func) {
node.DEFMETHOD("is_constant_expression", func);
diff --git a/test/compress/join_vars.js b/test/compress/join_vars.js
index 21b76aaa..89251266 100644
--- a/test/compress/join_vars.js
+++ b/test/compress/join_vars.js
@@ -1024,7 +1024,7 @@ issue_3856: {
expect_stdout: "undefined"
}
-issue_3916: {
+issue_3916_1: {
options = {
join_vars: true,
}
@@ -1044,8 +1044,8 @@ issue_3916: {
var o = {
p: "PASS",
__proto__: 42,
- q: "FAIL",
};
+ o.q = "FAIL";
o.__proto__ = {
p: "FAIL",
q: "PASS",
@@ -1056,6 +1056,62 @@ issue_3916: {
expect_stdout: "object PASS true PASS"
}
+issue_3916_2: {
+ options = {
+ join_vars: true,
+ }
+ input: {
+ var log = console.log, o = {};
+ o.p = "FAIL 1";
+ o.__proto__ = {
+ get p() {
+ return "FAIL 2";
+ },
+ set p(u) {
+ log("FAIL 3");
+ },
+ set q(v) {
+ log("PASS 1");
+ },
+ get q() {
+ return "PASS 3";
+ },
+ };
+ o.p = "PASS 2";
+ o.q = "FAIL 4";
+ log(o.p);
+ log(o.q);
+ }
+ expect: {
+ var log = console.log, o = {
+ p: "FAIL 1",
+ __proto__: {
+ get p() {
+ return "FAIL 2";
+ },
+ set p(u) {
+ log("FAIL 3");
+ },
+ set q(v) {
+ log("PASS 1");
+ },
+ get q() {
+ return "PASS 3";
+ },
+ },
+ };
+ o.p = "PASS 2";
+ o.q = "FAIL 4";
+ log(o.p);
+ log(o.q);
+ }
+ expect_stdout: [
+ "PASS 1",
+ "PASS 2",
+ "PASS 3",
+ ]
+}
+
assign_var: {
options = {
join_vars: true,
diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js
index 8ccaefe0..b48a418a 100644
--- a/test/ufuzz/index.js
+++ b/test/ufuzz/index.js
@@ -1188,7 +1188,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
var hadDefault = false;
- var s = [""];
+ var s = [ "" ];
canBreak = enableLoopControl(canBreak, CAN_BREAK);
while (n-- > 0) {
//hadDefault = n > 0; // disables weird `default` clause positioning (use when handling destabilizes)
@@ -1619,6 +1619,10 @@ var KEYS = [
"1.5",
"3",
].concat(SAFE_KEYS);
+SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
+SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
+SAFE_KEYS = SAFE_KEYS.concat(SAFE_KEYS);
+SAFE_KEYS.push("__proto__");
function getDotKey(assign) {
var key;
@@ -1736,8 +1740,9 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
function createObjectLiteral(recurmax, stmtDepth, canThrow) {
recurmax--;
- var obj = ["({"];
+ var obj = [ "({" ];
var offset = SUPPORT.spread_object ? 0 : SUPPORT.computed_key ? 2 : 4;
+ var has_proto = false;
for (var i = rng(6); --i >= 0;) switch (offset + rng(50 - offset)) {
case 0:
obj.push("..." + getVarName() + ",");
@@ -1753,7 +1758,12 @@ function createObjectLiteral(recurmax, stmtDepth, canThrow) {
obj.push(createObjectFunction(recurmax, stmtDepth, canThrow) + ",");
break;
default:
- obj.push(createObjectKey(recurmax, stmtDepth, canThrow) + ": " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ",");
+ if (has_proto || rng(200)) {
+ obj.push(createObjectKey(recurmax, stmtDepth, canThrow) + ": " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ",");
+ } else {
+ obj.push("__proto__: " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " || {},");
+ has_proto = true;
+ }
break;
}
obj.push("})");