Fix printing edge cases in Nullish Coalescing and Optional Ch… (#11255)
This is a mix of changes, most importantly: - Always print parens when mixing nullish coalescing and another logical - Fixes assignment in the callee of an optional chain, which now blocks #11248 Also, cleans up a bit of code, and removes an unnecessary parens around `class A extends new B {}`
This commit is contained in:
parent
420f2ee69a
commit
b1a589f0aa
@ -46,14 +46,7 @@ function isOrHasCallExpression(node) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.isMemberExpression(node)) {
|
return t.isMemberExpression(node) && isOrHasCallExpression(node.object);
|
||||||
return (
|
|
||||||
isOrHasCallExpression(node.object) ||
|
|
||||||
(!node.computed && isOrHasCallExpression(node.property))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function needsWhitespace(node, parent, type) {
|
export function needsWhitespace(node, parent, type) {
|
||||||
@ -97,18 +90,5 @@ export function needsParens(node, parent, printStack) {
|
|||||||
if (isOrHasCallExpression(node)) return true;
|
if (isOrHasCallExpression(node)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this check is for NullishCoalescing being used with LogicalOperators like && and ||
|
|
||||||
* For example when someone creates an ast programmaticaly like this
|
|
||||||
* t.logicalExpression(
|
|
||||||
* "??",
|
|
||||||
* t.logicalExpression("||", t.identifier("a"), t.identifier("b")),
|
|
||||||
* t.identifier("c"),
|
|
||||||
* );
|
|
||||||
* In the example above the AST is equivalent to writing a || b ?? c
|
|
||||||
* This is incorrect because NullishCoalescing when used with LogicalExpressions should have parenthesis
|
|
||||||
* The correct syntax is (a || b) ?? c, that is why we need parenthesis in this case
|
|
||||||
*/
|
|
||||||
if (t.isLogicalExpression(node) && parent.operator === "??") return true;
|
|
||||||
|
|
||||||
return find(expandedParens, node, parent, printStack);
|
return find(expandedParens, node, parent, printStack);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,8 +122,6 @@ export function Binary(node: Object, parent: Object): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UnionTypeAnnotation(node: Object, parent: Object): boolean {
|
export function UnionTypeAnnotation(node: Object, parent: Object): boolean {
|
||||||
@ -244,7 +242,8 @@ export function ConditionalExpression(node: Object, parent: Object): boolean {
|
|||||||
t.isBinary(parent) ||
|
t.isBinary(parent) ||
|
||||||
t.isConditionalExpression(parent, { test: node }) ||
|
t.isConditionalExpression(parent, { test: node }) ||
|
||||||
t.isAwaitExpression(parent) ||
|
t.isAwaitExpression(parent) ||
|
||||||
t.isOptionalMemberExpression(parent) ||
|
t.isOptionalMemberExpression(parent, { object: node }) ||
|
||||||
|
t.isOptionalCallExpression(parent, { callee: node }) ||
|
||||||
t.isTaggedTemplateExpression(parent) ||
|
t.isTaggedTemplateExpression(parent) ||
|
||||||
t.isTSTypeAssertion(parent) ||
|
t.isTSTypeAssertion(parent) ||
|
||||||
t.isTSAsExpression(parent)
|
t.isTSAsExpression(parent)
|
||||||
@ -272,16 +271,28 @@ export function OptionalCallExpression(node: Object, parent: Object): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AssignmentExpression(node: Object): boolean {
|
export function AssignmentExpression(
|
||||||
|
node: Object,
|
||||||
|
parent: Object,
|
||||||
|
printStack: Array<Object>,
|
||||||
|
): boolean {
|
||||||
if (t.isObjectPattern(node.left)) {
|
if (t.isObjectPattern(node.left)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return ConditionalExpression(...arguments);
|
return ConditionalExpression(node, parent, printStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NewExpression(node: Object, parent: Object): boolean {
|
export function LogicalExpression(node: Object, parent: Object): boolean {
|
||||||
return isClassExtendsClause(node, parent);
|
switch (node.operator) {
|
||||||
|
case "||":
|
||||||
|
if (!t.isLogicalExpression(parent)) return false;
|
||||||
|
return parent.operator === "??" || parent.operator === "&&";
|
||||||
|
case "&&":
|
||||||
|
return t.isLogicalExpression(parent, { operator: "??" });
|
||||||
|
case "??":
|
||||||
|
return t.isLogicalExpression(parent) && parent.operator !== "??";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk up the print stack to determine if our node can come first
|
// Walk up the print stack to determine if our node can come first
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
1 + (a = 2);
|
1 + (a = 2);
|
||||||
1 + (a += 2);
|
1 + (a += 2);
|
||||||
a = a || (a = {});
|
a = a || (a = {});
|
||||||
|
|
||||||
|
(a = b)();
|
||||||
|
(a = b)?.();
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
1 + (a = 2);
|
1 + (a = 2);
|
||||||
1 + (a += 2);
|
1 + (a += 2);
|
||||||
a = a || (a = {});
|
a = a || (a = {});
|
||||||
|
(a = b)();
|
||||||
|
(a = b)?.();
|
||||||
@ -12,7 +12,7 @@ class A6 extends class {} {}
|
|||||||
|
|
||||||
class A7 extends (B ? C : D) {}
|
class A7 extends (B ? C : D) {}
|
||||||
|
|
||||||
class A8 extends (new B()) {}
|
class A8 extends new B() {}
|
||||||
|
|
||||||
class A9 extends (B, C) {}
|
class A9 extends (B, C) {}
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,17 @@
|
|||||||
const foo = 'test'
|
const foo = 'test'
|
||||||
console.log((foo ?? '') == '')
|
console.log((foo ?? '') == '')
|
||||||
|
|
||||||
|
|
||||||
|
a ?? (b ?? c);
|
||||||
|
(a ?? b) ?? c;
|
||||||
|
|
||||||
|
a ?? (b || c);
|
||||||
|
a || (b ?? c);
|
||||||
|
(a ?? b) || c;
|
||||||
|
(a || b) ?? c;
|
||||||
|
|
||||||
|
a ?? (b && c);
|
||||||
|
a && (b ?? c);
|
||||||
|
(a ?? b) && c;
|
||||||
|
(a && b) ?? c;
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,12 @@
|
|||||||
const foo = 'test';
|
const foo = 'test';
|
||||||
console.log((foo ?? '') == '');
|
console.log((foo ?? '') == '');
|
||||||
|
a ?? b ?? c;
|
||||||
|
a ?? b ?? c;
|
||||||
|
a ?? (b || c);
|
||||||
|
a || (b ?? c);
|
||||||
|
(a ?? b) || c;
|
||||||
|
(a || b) ?? c;
|
||||||
|
a ?? (b && c);
|
||||||
|
a && (b ?? c);
|
||||||
|
(a ?? b) && c;
|
||||||
|
(a && b) ?? c;
|
||||||
@ -2,4 +2,14 @@ foo ||bar;
|
|||||||
(x => x)|| bar;
|
(x => x)|| bar;
|
||||||
(function a(x){return x;})|| 2;
|
(function a(x){return x;})|| 2;
|
||||||
0||(function(){return alpha;});
|
0||(function(){return alpha;});
|
||||||
a ?? (b || c);
|
|
||||||
|
a && (b && c);
|
||||||
|
(a && b) && c;
|
||||||
|
|
||||||
|
a || (b || c);
|
||||||
|
(a || b) || c;
|
||||||
|
|
||||||
|
a || (b && c);
|
||||||
|
a && (b || c);
|
||||||
|
(a || b) && c;
|
||||||
|
(a && b) || c;
|
||||||
|
|||||||
@ -9,4 +9,11 @@ foo || bar;
|
|||||||
return alpha;
|
return alpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
a ?? (b || c);
|
a && b && c;
|
||||||
|
a && b && c;
|
||||||
|
a || b || c;
|
||||||
|
a || b || c;
|
||||||
|
a || b && c;
|
||||||
|
a && (b || c);
|
||||||
|
(a || b) && c;
|
||||||
|
a && b || c;
|
||||||
Loading…
x
Reference in New Issue
Block a user