fix corner case with optional chain operator (#4927)
This commit is contained in:
@@ -790,10 +790,23 @@ function OutputStream(options) {
|
|||||||
if (p instanceof AST_Unary) return true;
|
if (p instanceof AST_Unary) return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function lhs_has_optional(node, output) {
|
||||||
|
var p = output.parent();
|
||||||
|
if (p instanceof AST_PropAccess && p.expression === node && is_lhs(p, output.parent(1))) {
|
||||||
|
// ++(foo?.bar).baz
|
||||||
|
// (foo?.()).bar = baz
|
||||||
|
do {
|
||||||
|
if (node.optional) return true;
|
||||||
|
node = node.expression;
|
||||||
|
} while (node.TYPE == "Call" || node instanceof AST_PropAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PARENS(AST_PropAccess, function(output) {
|
PARENS(AST_PropAccess, function(output) {
|
||||||
var node = this;
|
var node = this;
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_New && p.expression === node) {
|
if (p instanceof AST_New) {
|
||||||
|
if (p.expression !== node) return false;
|
||||||
// i.e. new (foo().bar)
|
// i.e. new (foo().bar)
|
||||||
//
|
//
|
||||||
// if there's one call into this subtree, then we need
|
// if there's one call into this subtree, then we need
|
||||||
@@ -805,20 +818,22 @@ function OutputStream(options) {
|
|||||||
} while (node instanceof AST_PropAccess);
|
} while (node instanceof AST_PropAccess);
|
||||||
return node.TYPE == "Call";
|
return node.TYPE == "Call";
|
||||||
}
|
}
|
||||||
|
return lhs_has_optional(node, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Call, function(output) {
|
PARENS(AST_Call, function(output) {
|
||||||
|
var node = this;
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_New) return p.expression === this;
|
if (p instanceof AST_New) return p.expression === node;
|
||||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||||
if (output.option("webkit")) {
|
if (output.option("webkit")
|
||||||
var g = output.parent(1);
|
&& node.expression instanceof AST_Function
|
||||||
return this.expression instanceof AST_Function
|
|
||||||
&& p instanceof AST_PropAccess
|
&& p instanceof AST_PropAccess
|
||||||
&& p.expression === this
|
&& p.expression === node) {
|
||||||
&& g instanceof AST_Assign
|
var g = output.parent(1);
|
||||||
&& g.left === p;
|
if (g instanceof AST_Assign && g.left === p) return true;
|
||||||
}
|
}
|
||||||
|
return lhs_has_optional(node, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_New, function(output) {
|
PARENS(AST_New, function(output) {
|
||||||
|
|||||||
@@ -43,6 +43,48 @@ ternary_decimal: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assign_parentheses_call: {
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
((() => o)?.()).p = "PASS";
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={};((()=>o)?.()).p="PASS";console.log(o.p);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_parentheses_dot: {
|
||||||
|
input: {
|
||||||
|
(console?.log).name.p = console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_exact: '(console?.log.name).p=console.log("PASS");'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_no_parentheses: {
|
||||||
|
input: {
|
||||||
|
console[console.log?.("PASS")] = 42;
|
||||||
|
}
|
||||||
|
expect_exact: 'console[console.log?.("PASS")]=42;'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_parentheses: {
|
||||||
|
input: {
|
||||||
|
var o = { p: 41 };
|
||||||
|
(function() {
|
||||||
|
return o;
|
||||||
|
}?.()).p++;
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect_exact: "var o={p:41};(function(){return o}?.()).p++;console.log(o.p);"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_vars_1: {
|
collapse_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user