Refactor comment printers to accept filter option (#18768)
This commit is contained in:
1 parent
187680371e
commit
04d90fd5b5
3 files changed
+120
-73
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
printComments,
|
||||
printCommentsSeparately,
|
||||
printLeadingComments,
|
||||
} from "../../main/comments/print.js";
|
||||
import {
|
||||
isSingleHtmlEventHandlerExpressionStatement,
|
||||
@@ -57,17 +57,13 @@ function printExpressionStatement(path, options, print) {
|
||||
);
|
||||
|
||||
// Print the type cast comment separately and print `;` before it
|
||||
// eslint-disable-next-line prettier-internal-rules/no-node-comments
|
||||
const { comments } = node;
|
||||
// eslint-disable-next-line prettier-internal-rules/no-node-comments
|
||||
node.comments = [typeCastComment];
|
||||
const typeCastCommentDoc = printCommentsSeparately(path, options).leading;
|
||||
// eslint-disable-next-line prettier-internal-rules/no-node-comments
|
||||
node.comments = comments;
|
||||
// Make it printed, so `printComments` will ignore it
|
||||
options[Symbol.for("printedComments")].add(typeCastComment);
|
||||
const typeCastCommentDoc = printLeadingComments(path, options, {
|
||||
filter: (comment) => comment === typeCastComment,
|
||||
});
|
||||
|
||||
return printComments(path, [";", typeCastCommentDoc, ...parts], options);
|
||||
return printComments(path, [";", typeCastCommentDoc, ...parts], options, {
|
||||
filter: (comment) => comment !== typeCastComment,
|
||||
});
|
||||
}
|
||||
|
||||
parts.unshift(";");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import AstPath from "../common/ast-path.js";
|
||||
import { cursor, inheritLabel } from "../document/index.js";
|
||||
import isNonEmptyArray from "../utilities/is-non-empty-array.js";
|
||||
import isObject from "../utilities/is-object.js";
|
||||
import { attachComments } from "./comments/attach.js";
|
||||
import { ensureAllCommentsPrinted, printComments } from "./comments/print.js";
|
||||
@@ -128,7 +129,11 @@ function callPluginPrintFunction(path, options, printPath, args, embeds) {
|
||||
|
||||
// We let JSXElement print its comments itself because it adds () around
|
||||
// UnionTypeAnnotation has to align the child without the comments
|
||||
if (printer.printComment && !printer.willPrintOwnComments?.(path, options)) {
|
||||
if (
|
||||
printer.printComment &&
|
||||
isNonEmptyArray(node.comments) &&
|
||||
!printer.willPrintOwnComments?.(path, options)
|
||||
) {
|
||||
// printComments will call the plugin print function and check for
|
||||
// comments to print
|
||||
doc = printComments(path, doc, options);
|
||||
|
||||
+107
-61
@@ -8,15 +8,17 @@ import {
|
||||
lineSuffix,
|
||||
} from "../../document/index.js";
|
||||
import hasNewline from "../../utilities/has-newline.js";
|
||||
import isNonEmptyArray from "../../utilities/is-non-empty-array.js";
|
||||
import isPreviousLineEmpty from "../../utilities/is-previous-line-empty.js";
|
||||
import { skipSpaces } from "../../utilities/skip.js";
|
||||
import skipNewline from "../../utilities/skip-newline.js";
|
||||
|
||||
/**
|
||||
* @import AstPath from "../../common/ast-path.js"
|
||||
* @import {Doc, HardLine, Line} from "../../document/index.js"
|
||||
*/
|
||||
@import AstPath from "../../common/ast-path.js"
|
||||
@import {Doc, HardLine, Line} from "../../document/index.js"
|
||||
@typedef {{
|
||||
filter?: (comment) => boolean,
|
||||
}} CommentPrintOptions
|
||||
*/
|
||||
|
||||
const returnTrue = () => true;
|
||||
|
||||
@@ -111,10 +113,9 @@ function printTrailingComment(path, options, previousComment) {
|
||||
|
||||
/**
|
||||
* @param {AstPath} path
|
||||
* @param {{
|
||||
* @param {CommentPrintOptions & {
|
||||
* indent?: boolean,
|
||||
* marker?: symbol | string,
|
||||
* filter?: (comment) => boolean,
|
||||
* }} [danglingCommentsPrintOptions]
|
||||
* @returns {Doc}
|
||||
*/
|
||||
@@ -123,89 +124,133 @@ function printDanglingComments(
|
||||
options,
|
||||
danglingCommentsPrintOptions = {},
|
||||
) {
|
||||
const { node } = path;
|
||||
|
||||
if (!isNonEmptyArray(node?.comments)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const {
|
||||
indent: shouldIndent = false,
|
||||
marker,
|
||||
filter = returnTrue,
|
||||
} = danglingCommentsPrintOptions;
|
||||
const danglingComments = new Set(
|
||||
path.node?.comments?.filter(
|
||||
(comment) =>
|
||||
!(
|
||||
comment.leading ||
|
||||
comment.trailing ||
|
||||
comment.marker !== marker ||
|
||||
!filter(comment)
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const parts = [];
|
||||
path.each(({ node: comment }) => {
|
||||
if (
|
||||
comment.leading ||
|
||||
comment.trailing ||
|
||||
comment.marker !== marker ||
|
||||
!filter(comment)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
parts.push(printComment(path, options));
|
||||
}, "comments");
|
||||
|
||||
if (parts.length === 0) {
|
||||
if (danglingComments.size === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const parts = path
|
||||
.map(
|
||||
({ node: comment }) =>
|
||||
danglingComments.has(comment) ? printComment(path, options) : "",
|
||||
"comments",
|
||||
)
|
||||
.filter(Boolean);
|
||||
|
||||
const doc = join(hardline, parts);
|
||||
return shouldIndent ? indent([hardline, doc]) : doc;
|
||||
}
|
||||
|
||||
/**
|
||||
@returns {{leading?: Doc, trailing?: Doc}}
|
||||
@param {AstPath} path
|
||||
@param {CommentPrintOptions} [printOptions]
|
||||
@returns {Doc}
|
||||
*/
|
||||
function printCommentsSeparately(path, options) {
|
||||
const value = path.node;
|
||||
if (!value) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const ignored = options[Symbol.for("printedComments")];
|
||||
const comments = (value.comments || []).filter(
|
||||
(comment) => !ignored.has(comment),
|
||||
function printLeadingComments(path, options, printOptions) {
|
||||
const printed = options[Symbol.for("printedComments")];
|
||||
const filter = printOptions?.filter ?? returnTrue;
|
||||
const leadingComments = new Set(
|
||||
path.node?.comments?.filter(
|
||||
(comment) => !printed?.has(comment) && comment.leading && filter(comment),
|
||||
),
|
||||
);
|
||||
|
||||
if (comments.length === 0) {
|
||||
return { leading: "", trailing: "" };
|
||||
if (leadingComments.size === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const leadingParts = [];
|
||||
const trailingParts = [];
|
||||
return path
|
||||
.map(
|
||||
({ node: comment }) =>
|
||||
leadingComments.has(comment) ? printLeadingComment(path, options) : "",
|
||||
"comments",
|
||||
)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
@param {AstPath} path
|
||||
@param {CommentPrintOptions} [printOptions]
|
||||
@returns {Doc}
|
||||
*/
|
||||
function printTrailingComments(path, options, printOptions) {
|
||||
const comments = path.node?.comments;
|
||||
const trailingComments = new Set(
|
||||
comments?.filter((comment) => comment.trailing),
|
||||
);
|
||||
const printed = options[Symbol.for("printedComments")];
|
||||
const filter = printOptions?.filter ?? returnTrue;
|
||||
const commentsShouldPrint = new Set(
|
||||
comments?.filter(
|
||||
(comment) =>
|
||||
trailingComments.has(comment) &&
|
||||
!printed?.has(comment) &&
|
||||
filter(comment),
|
||||
),
|
||||
);
|
||||
|
||||
if (commentsShouldPrint.size === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const docs = [];
|
||||
let printedTrailingComment;
|
||||
path.each(() => {
|
||||
const comment = path.node;
|
||||
if (ignored?.has(comment)) {
|
||||
path.each(({ node: comment }) => {
|
||||
if (!trailingComments.has(comment)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { leading, trailing } = comment;
|
||||
if (leading) {
|
||||
leadingParts.push(printLeadingComment(path, options));
|
||||
} else if (trailing) {
|
||||
printedTrailingComment = printTrailingComment(
|
||||
path,
|
||||
options,
|
||||
printedTrailingComment,
|
||||
);
|
||||
trailingParts.push(printedTrailingComment.doc);
|
||||
printedTrailingComment = printTrailingComment(
|
||||
path,
|
||||
options,
|
||||
printedTrailingComment,
|
||||
);
|
||||
|
||||
if (commentsShouldPrint.has(comment)) {
|
||||
docs.push(printedTrailingComment.doc);
|
||||
}
|
||||
}, "comments");
|
||||
|
||||
return { leading: leadingParts, trailing: trailingParts };
|
||||
return docs;
|
||||
}
|
||||
|
||||
function printComments(path, doc, options) {
|
||||
const { leading, trailing } = printCommentsSeparately(path, options);
|
||||
if (!leading && !trailing) {
|
||||
return doc;
|
||||
}
|
||||
return inheritLabel(doc, (doc) => [leading, doc, trailing]);
|
||||
/**
|
||||
@param {CommentPrintOptions} [printOptions]
|
||||
@returns {{leading: Doc, trailing: Doc}}
|
||||
*/
|
||||
function printCommentsSeparately(path, options, printOptions) {
|
||||
return {
|
||||
leading: printLeadingComments(path, options, printOptions),
|
||||
trailing: printTrailingComments(path, options, printOptions),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@param {CommentPrintOptions} [printOptions]
|
||||
@returns {Doc}
|
||||
*/
|
||||
function printComments(path, doc, options, printOptions) {
|
||||
const leading = printLeadingComments(path, options, printOptions);
|
||||
const trailing = printTrailingComments(path, options, printOptions);
|
||||
return leading || trailing
|
||||
? inheritLabel(doc, (doc) => [leading, doc, trailing])
|
||||
: doc;
|
||||
}
|
||||
|
||||
function ensureAllCommentsPrinted(options) {
|
||||
@@ -231,4 +276,5 @@ export {
|
||||
printComments,
|
||||
printCommentsSeparately,
|
||||
printDanglingComments,
|
||||
printLeadingComments,
|
||||
};
|
||||
Reference in new issue
Block a user