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.
|
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`
|
### `hardlineWithoutBreakParent` and `literallineWithoutBreakParent`
|
||||||
|
|
||||||
_Added in v2.3.0_
|
_Added in v2.3.0_
|
||||||
|
|||||||
@@ -259,6 +259,10 @@ function addAlignmentToDoc(doc, size, tabWidth) {
|
|||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function label(label, contents) {
|
||||||
|
return { type: "label", label, contents };
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
concat,
|
concat,
|
||||||
join,
|
join,
|
||||||
@@ -284,4 +288,5 @@ module.exports = {
|
|||||||
dedent,
|
dedent,
|
||||||
hardlineWithoutBreakParent,
|
hardlineWithoutBreakParent,
|
||||||
literallineWithoutBreakParent,
|
literallineWithoutBreakParent,
|
||||||
|
label,
|
||||||
};
|
};
|
||||||
@@ -173,6 +173,10 @@ function printDocToDebug(doc) {
|
|||||||
return "lineSuffixBoundary";
|
return "lineSuffixBoundary";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doc.type === "label") {
|
||||||
|
return `label(${JSON.stringify(doc.label)}, ${printDoc(doc.contents)})`;
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error("Unknown doc type " + doc.type);
|
throw new Error("Unknown doc type " + doc.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,9 @@ function fits(next, restCommands, width, options, hasLineSuffix, mustBeFlat) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "label":
|
||||||
|
cmds.push([ind, mode, doc.contents]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,6 +556,9 @@ function printDocToString(doc, options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "label":
|
||||||
|
cmds.push([ind, mode, doc.contents]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,8 +227,10 @@ function stripDocTrailingHardlineFromDoc(doc) {
|
|||||||
switch (doc.type) {
|
switch (doc.type) {
|
||||||
case "align":
|
case "align":
|
||||||
case "indent":
|
case "indent":
|
||||||
|
case "indent-if-break":
|
||||||
case "group":
|
case "group":
|
||||||
case "line-suffix": {
|
case "line-suffix":
|
||||||
|
case "label": {
|
||||||
const contents = stripDocTrailingHardlineFromDoc(doc.contents);
|
const contents = stripDocTrailingHardlineFromDoc(doc.contents);
|
||||||
return { ...doc, contents };
|
return { ...doc, contents };
|
||||||
}
|
}
|
||||||
@@ -270,6 +272,7 @@ function cleanDocFn(doc) {
|
|||||||
break;
|
break;
|
||||||
case "align":
|
case "align":
|
||||||
case "indent":
|
case "indent":
|
||||||
|
case "indent-if-break":
|
||||||
case "line-suffix":
|
case "line-suffix":
|
||||||
if (!doc.contents) {
|
if (!doc.contents) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -24,7 +24,15 @@ const {
|
|||||||
const { locEnd } = require("../loc");
|
const { locEnd } = require("../loc");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
builders: { join, hardline, group, indent, conditionalGroup, breakParent },
|
builders: {
|
||||||
|
join,
|
||||||
|
hardline,
|
||||||
|
group,
|
||||||
|
indent,
|
||||||
|
conditionalGroup,
|
||||||
|
breakParent,
|
||||||
|
label,
|
||||||
|
},
|
||||||
utils: { willBreak },
|
utils: { willBreak },
|
||||||
} = require("../../document");
|
} = require("../../document");
|
||||||
const printCallArguments = require("./call-arguments");
|
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:
|
// We don't want to print in one line if at least one of these conditions occurs:
|
||||||
// * the chain has comments,
|
// * the chain has comments,
|
||||||
// * the chain is an expression statement and all the arguments are literal-like ("fluent configuration" pattern),
|
// * 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) ||
|
printedGroups.slice(0, -1).some(willBreak) ||
|
||||||
lastGroupWillBreakAndOtherCallsHaveFunctionArguments()
|
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 [
|
return label("member-chain", 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]),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = printMemberChain;
|
module.exports = printMemberChain;
|
||||||
@@ -66,6 +66,7 @@ describe("API", () => {
|
|||||||
indentIfBreak,
|
indentIfBreak,
|
||||||
group,
|
group,
|
||||||
line,
|
line,
|
||||||
|
label,
|
||||||
} = builders;
|
} = builders;
|
||||||
|
|
||||||
expect(formatDoc([indent(hardline), indent(literalline)])).toBe(
|
expect(formatDoc([indent(hardline), indent(literalline)])).toBe(
|
||||||
@@ -86,5 +87,9 @@ describe("API", () => {
|
|||||||
expect(
|
expect(
|
||||||
formatDoc(indentIfBreak(group(["1", line, "2"]), { groupId: "Q" }))
|
formatDoc(indentIfBreak(group(["1", line, "2"]), { groupId: "Q" }))
|
||||||
).toBe('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