RFC: label doc (#10275)

* RFC: label doc

* Update functions in doc-utils
This commit is contained in:
Georgii Dolzhykov authored and GitHub committed 2021-02-10 17:08:54 +02:00
1 parent 91c0d58c4a
commit 662cdb04db
7 files changed
+57 -10

No files matched your search

+12
View File
@@ -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_
+5
View File
@@ -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,
};
+4
View File
@@ -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);
}
+6
View File
@@ -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:
}
}
+4 -1
View File
@@ -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 "";
+21 -9
View File
@@ -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;
+5
View File
@@ -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"]))'
);
});
});