fix corner cases in properties (#5178)

fixes #5177
This commit is contained in:
Alex Lam S.L
2021-11-16 20:21:44 +00:00
committed by GitHub
parent 77f7ae5ba2
commit ae5c3ee8a1
6 changed files with 172 additions and 25 deletions

View File

@@ -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);
@@ -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) {
@@ -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;
@@ -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 }),
});
}

View File

@@ -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);
}

View File

@@ -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");
}