Improve format of member chain with ChainExpression (#18729)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-01-24 04:53:28 +08:00
1 parent 0268fdbce5
commit 8a8fefa580
7 files changed
+284 -50

No files matched your search

+2 -49
View File
@@ -1,3 +1,4 @@
import { cleanChainExpression } from "./clean/chain-expression.js";
import {
isArrayExpression,
isBigIntLiteral,
@@ -45,46 +46,6 @@ function cleanKey(cloned, original, property) {
}
}
function cleanEstreeChainExpression(node) {
while (true) {
if (node.type === "MemberExpression") {
if (node.object.type === "ChainExpression") {
node.object = node.object.expression;
}
node = node.object;
continue;
}
if (node.type === "CallExpression") {
if (node.callee.type === "ChainExpression") {
node.callee = node.callee.expression;
}
node = node.callee;
continue;
}
return;
}
}
function cleanBabelChainExpression(node) {
while (true) {
if (node.type === "MemberExpression") {
node.type = "OptionalMemberExpression";
node = node.object;
continue;
}
if (node.type === "CallExpression") {
node.type = "OptionalCallExpression";
node = node.callee;
continue;
}
return;
}
}
/**
@param {Node} original
@param {any} cloned
@@ -264,15 +225,7 @@ function clean(original, cloned, parent) {
}
// We don't add parentheses to `(a?.b)?.c`
if (original.type === "ChainExpression") {
cleanEstreeChainExpression(cloned.expression);
}
if (original.type === "OptionalMemberExpression") {
cleanBabelChainExpression(cloned.object);
}
if (original.type === "OptionalCallExpression") {
cleanBabelChainExpression(cloned.callee);
}
cleanChainExpression(cloned, original);
// https://github.com/babel/babel/issues/17719
if (
+72
View File
@@ -0,0 +1,72 @@
import {
isCallExpression,
isChainElementWrapper,
isMemberExpression,
} from "../utilities/index.js";
/**
@import {Node} from "../types/estree.js"
*/
function cleanChainExpression(cloned, original) {
// We don't add parentheses to `(a?.b)?.c`
if (original.type === "ChainExpression") {
cleanEstreeChainExpression(cloned);
}
if (
original.type === "OptionalMemberExpression" ||
original.type === "OptionalCallExpression"
) {
cleanBabelChainExpression(cloned);
}
}
function getChainElementProperty(node) {
if (isMemberExpression(node)) {
return "object";
}
if (isCallExpression(node)) {
return "callee";
}
if (isChainElementWrapper(node)) {
return "expression";
}
}
function getChainElement(node) {
const property = getChainElementProperty(node);
if (property) {
return node[property];
}
}
function cleanEstreeChainExpression(node) {
for (
node = getChainElement(node);
node.type === "MemberExpression" ||
node.type === "CallExpression" ||
node.type === "TSNonNullExpression";
node = getChainElement(node)
) {
const property = getChainElementProperty(node);
const child = node[property];
if (child.type === "ChainExpression") {
node[property] = child.expression;
}
}
}
function cleanBabelChainExpression(node) {
for (
node = getChainElement(node);
node.type === "MemberExpression" || node.type === "CallExpression";
node = getChainElement(node)
) {
node.type = `Optional${node.type}`;
}
}
export { cleanChainExpression };
+7 -1
View File
@@ -32,7 +32,7 @@ import { printOptionalToken } from "./miscellaneous.js";
/**
* @import {Doc} from "../../document/index.js"
* @typedef {{ node: any, printed: Doc, needsParens?: boolean, shouldInline?: boolean, hasTrailingEmptyLine?: boolean }} PrintedNode
* @typedef {{ node: any, printed: Doc, shouldInline?: boolean, hasTrailingEmptyLine?: boolean }} PrintedNode
*/
// We detect calls on member expressions specially to format a
@@ -126,6 +126,11 @@ function printMemberChain(path, options, print) {
),
});
path.call(rec, "object");
} else if (
node.type === "ChainExpression" &&
!needsParentheses(path, options)
) {
path.call(rec, "expression");
} else if (
node.type === "TSNonNullExpression" &&
!needsParentheses(path, options)
@@ -190,6 +195,7 @@ function printMemberChain(path, options, print) {
for (; i < printedNodes.length; ++i) {
if (
printedNodes[i].node.type === "TSNonNullExpression" ||
printedNodes[i].node.type === "ChainExpression" ||
isCallExpression(printedNodes[i].node) ||
(isMemberExpression(printedNodes[i].node) &&
printedNodes[i].node.computed &&
@@ -182,6 +182,45 @@ const randomFuncion = (value) => {
================================================================================
`;
exports[`member-chain.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript", "flow"]
printWidth: 80
| printWidth
=====================================input======================================
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
=====================================output=====================================
bifornCringerMoshedPerplexSawder = (glimseGlyphsHazardNoopsTieTie
?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder =
glimseGlyphsHazardNoopsTieTie?.averredBathersBoxroomBuggyNurl?.anodyneCondosMalateOverateRetinol?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
================================================================================
`;
exports[`member-expression.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript", "flow"]
@@ -0,0 +1,17 @@
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
@@ -219,6 +219,102 @@ const theValue3 = Object.entries(someLongObjectName).filter(([listingId]) =>
================================================================================
`;
exports[`member-chain.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)!
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)!
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;
=====================================output=====================================
bifornCringerMoshedPerplexSawder = (glimseGlyphsHazardNoopsTieTie
?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!).annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (glimseGlyphsHazardNoopsTieTie
?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol)!.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (glimseGlyphsHazardNoopsTieTie
?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;
bifornCringerMoshedPerplexSawder =
glimseGlyphsHazardNoopsTieTie?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!?.annularCooeedSplicesWalksWayWay.annularCooeedSplicesWalksWayWay(
annularCooeedSplicesWalksWayWay,
)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (glimseGlyphsHazardNoopsTieTie
?.averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol)!?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder =
glimseGlyphsHazardNoopsTieTie?.averredBathersBoxroomBuggyNurl?.anodyneCondosMalateOverateRetinol?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;
================================================================================
`;
exports[`member-expression.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -0,0 +1,51 @@
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)!
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol!
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)!
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay();
bifornCringerMoshedPerplexSawder = (
glimseGlyphsHazardNoopsTieTie
?. averredBathersBoxroomBuggyNurl
?.anodyneCondosMalateOverateRetinol
)
?.annularCooeedSplicesWalksWayWay
.annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay)
.annularCooeedSplicesWalksWayWay()!;