RFC: label doc (#10275)
* RFC: label doc * Update functions in doc-utils
This commit is contained in:
1 parent
91c0d58c4a
commit
662cdb04db
7 files changed
+57
-10
No files matched your search
+12
@@ -271,6 +271,18 @@ With `negate: true`, corresponds to `ifBreak(doc, indent(doc), { groupId })`
|
||||
|
||||
It doesn't make sense to apply `indentIfBreak` to the current group because "indent if the current group is broken" is the normal behavior of `indent`. That's why `groupId` is required.
|
||||
|
||||
### `label`
|
||||
|
||||
_Added in v2.3.0_
|
||||
|
||||
```ts
|
||||
declare function label(label: string, doc: Doc): Doc;
|
||||
```
|
||||
|
||||
Mark a doc with a string label. This doesn't affect how the doc is printed, but can be useful for heuristics based on doc introspection.
|
||||
|
||||
E.g., to decide how to print an assignment expression, we might want to know whether its right-hand side has been printed as a method call chain, not as a plain function call. If the method chain printing code uses `label` to mark its result, checking that condition can be as easy as `rightHandSideDoc.label === 'method-chain'`.
|
||||
|
||||
### `hardlineWithoutBreakParent` and `literallineWithoutBreakParent`
|
||||
|
||||
_Added in v2.3.0_
|
||||
|
||||
@@ -259,6 +259,10 @@ function addAlignmentToDoc(doc, size, tabWidth) {
|
||||
return aligned;
|
||||
}
|
||||
|
||||
function label(label, contents) {
|
||||
return { type: "label", label, contents };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
concat,
|
||||
join,
|
||||
@@ -284,4 +288,5 @@ module.exports = {
|
||||
dedent,
|
||||
hardlineWithoutBreakParent,
|
||||
literallineWithoutBreakParent,
|
||||
label,
|
||||
};
|
||||
@@ -173,6 +173,10 @@ function printDocToDebug(doc) {
|
||||
return "lineSuffixBoundary";
|
||||
}
|
||||
|
||||
if (doc.type === "label") {
|
||||
return `label(${JSON.stringify(doc.label)}, ${printDoc(doc.contents)})`;
|
||||
}
|
||||
|
||||
throw new Error("Unknown doc type " + doc.type);
|
||||
}
|
||||
|
||||
|
||||
@@ -258,6 +258,9 @@ function fits(next, restCommands, width, options, hasLineSuffix, mustBeFlat) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case "label":
|
||||
cmds.push([ind, mode, doc.contents]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,6 +556,9 @@ function printDocToString(doc, options) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "label":
|
||||
cmds.push([ind, mode, doc.contents]);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +227,10 @@ function stripDocTrailingHardlineFromDoc(doc) {
|
||||
switch (doc.type) {
|
||||
case "align":
|
||||
case "indent":
|
||||
case "indent-if-break":
|
||||
case "group":
|
||||
case "line-suffix": {
|
||||
case "line-suffix":
|
||||
case "label": {
|
||||
const contents = stripDocTrailingHardlineFromDoc(doc.contents);
|
||||
return { ...doc, contents };
|
||||
}
|
||||
@@ -270,6 +272,7 @@ function cleanDocFn(doc) {
|
||||
break;
|
||||
case "align":
|
||||
case "indent":
|
||||
case "indent-if-break":
|
||||
case "line-suffix":
|
||||
if (!doc.contents) {
|
||||
return "";
|
||||
|
||||
@@ -24,7 +24,15 @@ const {
|
||||
const { locEnd } = require("../loc");
|
||||
|
||||
const {
|
||||
builders: { join, hardline, group, indent, conditionalGroup, breakParent },
|
||||
builders: {
|
||||
join,
|
||||
hardline,
|
||||
group,
|
||||
indent,
|
||||
conditionalGroup,
|
||||
breakParent,
|
||||
label,
|
||||
},
|
||||
utils: { willBreak },
|
||||
} = require("../../document");
|
||||
const printCallArguments = require("./call-arguments");
|
||||
@@ -374,6 +382,8 @@ function printMemberChain(path, options, print) {
|
||||
);
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
// We don't want to print in one line if at least one of these conditions occurs:
|
||||
// * the chain has comments,
|
||||
// * the chain is an expression statement and all the arguments are literal-like ("fluent configuration" pattern),
|
||||
@@ -389,16 +399,18 @@ function printMemberChain(path, options, print) {
|
||||
printedGroups.slice(0, -1).some(willBreak) ||
|
||||
lastGroupWillBreakAndOtherCallsHaveFunctionArguments()
|
||||
) {
|
||||
return group(expanded);
|
||||
result = group(expanded);
|
||||
} else {
|
||||
result = [
|
||||
// We only need to check `oneLine` because if `expanded` is chosen
|
||||
// that means that the parent group has already been broken
|
||||
// naturally
|
||||
willBreak(oneLine) || shouldHaveEmptyLineBeforeIndent ? breakParent : "",
|
||||
conditionalGroup([oneLine, expanded]),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
// We only need to check `oneLine` because if `expanded` is chosen
|
||||
// that means that the parent group has already been broken
|
||||
// naturally
|
||||
willBreak(oneLine) || shouldHaveEmptyLineBeforeIndent ? breakParent : "",
|
||||
conditionalGroup([oneLine, expanded]),
|
||||
];
|
||||
return label("member-chain", result);
|
||||
}
|
||||
|
||||
module.exports = printMemberChain;
|
||||
@@ -66,6 +66,7 @@ describe("API", () => {
|
||||
indentIfBreak,
|
||||
group,
|
||||
line,
|
||||
label,
|
||||
} = builders;
|
||||
|
||||
expect(formatDoc([indent(hardline), indent(literalline)])).toBe(
|
||||
@@ -86,5 +87,9 @@ describe("API", () => {
|
||||
expect(
|
||||
formatDoc(indentIfBreak(group(["1", line, "2"]), { groupId: "Q" }))
|
||||
).toBe('indentIfBreak(group(["1", line, "2"]), { groupId: "Q" })');
|
||||
|
||||
expect(formatDoc(label("foo", group(["1", line, "2"])))).toBe(
|
||||
'label("foo", group(["1", line, "2"]))'
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user