Skip to content

Commit

Permalink
fix corner cases in properties (#5178)
Browse files Browse the repository at this point in the history
fixes #5177
  • Loading branch information
alexlamsl committed Nov 16, 2021
1 parent 77f7ae5 commit ae5c3ee
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 25 deletions.
55 changes: 34 additions & 21 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -9255,6 +9255,13 @@ merge(Compressor.prototype, {
}) : arg);
}

function avoid_await_yield(parent_scope) {
var avoid = [];
if (is_async(parent_scope)) avoid.push("await");
if (is_generator(parent_scope)) avoid.push("yield");
return avoid.length && makePredicate(avoid);
}

OPT(AST_Call, function(self, compressor) {
var exp = self.expression;
var terminated = trim_optional_chain(self, compressor);
Expand Down Expand Up @@ -9770,16 +9777,8 @@ merge(Compressor.prototype, {
return args;
}

function avoid_await_yield() {
var avoid = [];
var parent_scope = scope || compressor.find_parent(AST_Scope);
if (is_async(parent_scope)) avoid.push("await");
if (is_generator(parent_scope)) avoid.push("yield");
return avoid.length && makePredicate(avoid);
}

function safe_from_await_yield(node) {
var avoid = avoid_await_yield();
var avoid = avoid_await_yield(scope || compressor.find_parent(AST_Scope));
if (!avoid) return true;
var safe = true;
var tw = new TreeWalker(function(node) {
Expand Down Expand Up @@ -9856,7 +9855,7 @@ merge(Compressor.prototype, {
return def.references.length - def.replaced < 2 && def.orig[0] instanceof AST_SymbolFunarg;
})) return;
var abort = false;
var avoid = avoid_await_yield();
var avoid = avoid_await_yield(scope || compressor.find_parent(AST_Scope));
var begin;
var in_order = [];
var side_effects = false;
Expand Down Expand Up @@ -12373,19 +12372,33 @@ merge(Compressor.prototype, {
for (var i = props.length; --i >= 0;) {
var prop = props[i];
if (prop.key !== key) continue;
if (!all(props, can_hoist_property)) break;
if (!safe_to_flatten(prop.value, compressor)) break;
props = props.map(function(prop) {
return prop.value;
});
if (prop instanceof AST_ObjectMethod
&& prop.value instanceof AST_Function
&& !(compressor.parent() instanceof AST_Call)) {
if (prop.value.uses_arguments) break;
props[i] = make_node(AST_Arrow, prop.value, prop.value);
if (!all(props, can_hoist_property)) return;
if (!safe_to_flatten(prop.value, compressor)) return;
var values = [];
for (var j = 0; j < props.length; j++) {
var value = props[j].value;
if (props[j] instanceof AST_ObjectMethod) {
var arrow = !(value.uses_arguments || is_generator(value) || value.contains_this());
if (arrow) {
var avoid = avoid_await_yield(compressor.find_parent(AST_Scope));
value.each_argname(function(argname) {
if (avoid[argname.name]) arrow = false;
});
}
var ctor;
if (arrow) {
ctor = is_async(value) ? AST_AsyncArrow : AST_Arrow;
} else if (i === j && !(compressor.parent() instanceof AST_Call)) {
return;
} else {
ctor = value.CTOR;
}
value = make_node(ctor, value, value);
}
values.push(value);
}
return make_node(AST_Sub, this, {
expression: make_node(AST_Array, expr, { elements: props }),
expression: make_node(AST_Array, expr, { elements: values }),
property: make_node(AST_Number, this, { value: i }),
});
}
Expand Down
5 changes: 3 additions & 2 deletions lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -1152,8 +1152,9 @@ function OutputStream(options) {
});
}
function print_arrow(self, output) {
if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
self.argnames[0].print(output);
var argname = self.argnames.length == 1 && !self.rest && self.argnames[0];
if (argname instanceof AST_SymbolFunarg && argname.name != "yield") {
argname.print(output);
} else {
print_funargs(self, output);
}
Expand Down
5 changes: 5 additions & 0 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,11 @@ function parse($TEXT, options) {
}
if (node instanceof AST_SymbolFunarg) return node;
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
if (node instanceof AST_Yield) return new AST_SymbolFunarg({
start: node.start,
name: "yield",
end: node.end,
});
token_error(node.start, "Invalid arrow parameter");
}

Expand Down
28 changes: 27 additions & 1 deletion test/compress/awaits.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ object_function: {
}).f();
}
expect: {
(async function() {
(async () => {
console.log("PASS");
})();
}
Expand Down Expand Up @@ -2212,3 +2212,29 @@ issue_5159_2: {
]
node_version: ">=8"
}

issue_5177: {
options = {
properties: true,
}
input: {
(async function() {
return {
p(await) {},
}.p;
})().then(function(a) {
console.log(typeof a);
});
}
expect: {
(async function() {
return {
p(await) {},
}.p;
})().then(function(a) {
console.log(typeof a);
});
}
expect_stdout: "function"
node_version: ">=8"
}
68 changes: 68 additions & 0 deletions test/compress/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -1510,3 +1510,71 @@ issue_5093_quote_style: {
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
expect_stdout: "PASS"
}

object_methods: {
options = {
properties: true,
}
input: {
({
p() {
console.log("FAIL 1");
},
*q() {
console.log("FAIL 2");
},
async r() {
console.log("FAIL 3");
},
async *s() {
console.log("PASS");
},
}).s().next();
}
expect: {
[
() => {
console.log("FAIL 1");
},
function*() {
console.log("FAIL 2");
},
async () => {
console.log("FAIL 3");
},
async function*() {
console.log("PASS");
},
][3]().next();
}
expect_stdout: "PASS"
node_version: ">=10"
}

issue_5177: {
options = {
properties: true,
}
input: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect: {
var a = "FAIL";
var o = { a: "PASS" };
o.p = {
q() {
return this.a;
},
}.q;
console.log(o.p());
}
expect_stdout: "PASS"
node_version: ">=4"
}
36 changes: 35 additions & 1 deletion test/compress/yields.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pause_resume: {
node_version: ">=4"
}

arrow_yield: {
arrow_yield_1: {
input: {
yield = "PASS";
console.log(function*() {
Expand All @@ -108,6 +108,18 @@ arrow_yield: {
node_version: ">=4"
}

arrow_yield_2: {
input: {
console.log(typeof function *() {
// Syntax error on Node.js v6+
return (yield) => {};
}().next().value);
}
expect_exact: "console.log(typeof function*(){return(yield)=>{}}().next().value);"
expect_stdout: "function"
node_version: "4"
}

for_of: {
input: {
function* f() {
Expand Down Expand Up @@ -1275,3 +1287,25 @@ issue_5076: {
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5177: {
options = {
properties: true,
}
input: {
console.log(typeof function*() {
return {
p(yield) {},
}.p;
}().next().value);
}
expect: {
console.log(typeof function*() {
return {
p(yield) {},
}.p;
}().next().value);
}
expect_stdout: "function"
node_version: ">=4"
}

0 comments on commit ae5c3ee

Please sign in to comment.