fix corner case in objects (#5214)

fixes #5213
This commit is contained in:
Alex Lam S.L
2021-12-09 22:02:22 +00:00
committed by GitHub
parent 9e4c4c995c
commit 57a9519c3d
3 changed files with 43 additions and 11 deletions

View File

@@ -12560,7 +12560,8 @@ Compressor.prototype.compress = function(node) {
var found = false; var found = false;
var generated = false; var generated = false;
var keep_duplicate = compressor.has_directive("use strict"); var keep_duplicate = compressor.has_directive("use strict");
var keys = new Dictionary(); var keys = [];
var map = new Dictionary();
var values = []; var values = [];
self.properties.forEach(function(prop) { self.properties.forEach(function(prop) {
if (!(prop instanceof AST_Spread)) return process(prop); if (!(prop instanceof AST_Spread)) return process(prop);
@@ -12603,19 +12604,27 @@ Compressor.prototype.compress = function(node) {
return make_node(AST_Object, self, { properties: values }); return make_node(AST_Object, self, { properties: values });
function flush() { function flush() {
keys.each(function(props) { keys.forEach(function(key) {
if (props.length == 1) return values.push(props[0]); var props = map.get(key);
switch (props.length) {
case 0:
return;
case 1:
return values.push(props[0]);
}
changed = true; changed = true;
var tail = keep_duplicate && !generated && props.pop(); var tail = keep_duplicate && !generated && props.pop();
values.push(props.length == 1 ? props[0] : make_node(AST_ObjectKeyVal, self, { values.push(props.length == 1 ? props[0] : make_node(AST_ObjectKeyVal, self, {
key: props[0].key, key: props[0].key,
value: make_sequence(self, props.map(function(prop) { value: make_sequence(self, props.map(function(prop) {
return prop.value; return prop.value;
})) })),
})); }));
if (tail) values.push(tail); if (tail) values.push(tail);
props.length = 0;
}); });
keys = new Dictionary(); keys = [];
map = new Dictionary();
} }
function process(prop) { function process(prop) {
@@ -12631,14 +12640,15 @@ Compressor.prototype.compress = function(node) {
} }
if (can_hoist_property(prop)) { if (can_hoist_property(prop)) {
if (prop.value.has_side_effects(compressor)) flush(); if (prop.value.has_side_effects(compressor)) flush();
keys.add(key, prop); keys.push(key);
map.add(key, prop);
} else { } else {
flush(); flush();
values.push(prop); values.push(prop);
} }
if (found && !generated && typeof key == "string" && RE_POSITIVE_INTEGER.test(key)) { if (found && !generated && typeof key == "string" && RE_POSITIVE_INTEGER.test(key)) {
generated = true; generated = true;
if (keys.has(key)) prop = keys.get(key)[0]; if (map.has(key)) prop = map.get(key)[0];
prop.key = make_node(AST_Number, prop, { value: +key }); prop.key = make_node(AST_Number, prop, { value: +key });
} }
} }

View File

@@ -198,9 +198,9 @@ numeric_literal: {
expect_exact: [ expect_exact: [
'var obj = {', 'var obj = {',
' 0: 0,', ' 0: 0,',
' 37: 4,',
' 42: 3,',
' "-0": 1,', ' "-0": 1,',
' 42: 3,',
' 37: 4,',
' o: 5,', ' o: 5,',
' 1e42: 8,', ' 1e42: 8,',
' b: 7', ' b: 7',
@@ -521,3 +521,25 @@ issue_4415: {
expect_stdout: "PASS" expect_stdout: "PASS"
node_version: ">=4" node_version: ">=4"
} }
issue_5213: {
options = {
objects: true,
}
input: {
var a = "FAIL";
console.log({
p: a = "PASS",
0: a,
p: null,
}[0]);
}
expect: {
var a = "FAIL";
console.log({
p: (a = "PASS", null),
0: a,
}[0]);
}
expect_stdout: "PASS"
}

View File

@@ -252,7 +252,7 @@ function run_code_vm(code, toplevel, timeout) {
var ctx = vm.createContext({ console: console }); var ctx = vm.createContext({ console: console });
// for Node.js v6 // for Node.js v6
vm.runInContext(setup_code, ctx); vm.runInContext(setup_code, ctx);
vm.runInContext(toplevel ? "(function(){" + code + "})();" : code, ctx, { timeout: timeout }); vm.runInContext(toplevel ? "(function(){\n" + code + "\n})();" : code, ctx, { timeout: timeout });
// for Node.js v4 // for Node.js v4
return strip_color_codes(stdout.replace(/\b(Array \[|Object {)/g, function(match) { return strip_color_codes(stdout.replace(/\b(Array \[|Object {)/g, function(match) {
return match.slice(-1); return match.slice(-1);
@@ -266,7 +266,7 @@ function run_code_vm(code, toplevel, timeout) {
function run_code_exec(code, toplevel, timeout) { function run_code_exec(code, toplevel, timeout) {
if (toplevel) { if (toplevel) {
code = setup_code + "(function(){" + code + "})();"; code = setup_code + "(function(){\n" + code + "\n})();";
} else { } else {
code = code.replace(/^((["'])[^"']*\2(;|$))?/, function(directive) { code = code.replace(/^((["'])[^"']*\2(;|$))?/, function(directive) {
return directive + setup_code; return directive + setup_code;